1. //74HC165 start
  2. //--------------------------------------------------------------------------------------------------------------
  3. /* Width of pulse to trigger the shift register to read and latch.
  4. */
  5. #define PULSE_WIDTH_USEC 1
  6. /* Optional delay between shift register reads.
  7. */
  8. #define POLL_DELAY_MSEC 1
  9. /* You will need to change the "int" to "long" If the
  10. * NUMBER_OF_SHIFT_CHIPS is higher than 2.
  11. */
  12. int ploadPin = 5; // Connects to Parallel load pin the 165
  13. int clockEnablePin = 6; // Connects to Clock Enable pin the 165
  14. int dataPin = 7; // Connects to the Q7 pin the 165
  15. int clockPin = 8; // Connects to the Clock pin the 165
  16. /* How many shift register chips are daisy-chained.
  17. */
  18. const byte NUMBER_OF_SHIFT_CHIPS = 6;
  19. /* Width of data (how many ext lines).
  20. */
  21. const byte DATA_WIDTH = NUMBER_OF_SHIFT_CHIPS * 8;
  22. /* This function is essentially a "shift-in" routine reading the
  23. * serial Data from the shift register chips and representing
  24. * the state of those pins in an unsigned integer (or long).
  25. */
  26. //--------------------------------------------------------------------------------------------------------------
  27. int pinA[] = {LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW}; // encoder read A
  28. int pinB[] = {LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW}; // encoder read B
  29. int pinALast[] = {LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW};
  30. int aVal[] = {LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW};
  31. int EncoderChannel[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}; // encoder channel
  32. int encoderPosCount[] = {65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65, 65}; // encoder start value
  33. int led[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
  34. int led_state_old[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
  35. int ButtonChannel[] = {21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40}; // button Channel
  36. int taste[] = {LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW}; // button state
  37. int tasteAlt[] = {LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW}; // button state old
  38. int buttons = 16;
  39. int encoders = 16;
  40. int encodernums = 32;
  41. int shift[DATA_WIDTH];
  42. int shift_old[DATA_WIDTH];
  43. int count = 0;
  44. int countA = 0;
  45. int countB = 0;
  46. int data = LOW;
  47. unsigned long millisold = 10000;
  48. int noteOn = 176; //note state
  49. byte commandByte; // read note state
  50. byte noteByte; // read Midi Channel
  51. byte velocityByte; // read Midi value
  52. int adjust = 0;
  53. int adjustold = 0;
  54. int adjuststate = 0;
  55. //74HC595 start
  56. //--------------------------------------------------------------------------------------------------------------
  57. #include <ShiftRegister74HC595.h>
  58. // create shift register object (number of shift registers, data pin, clock pin, latch pin)
  59. ShiftRegister74HC595 shifter0 (14, 2, 4, 3);
  60. ShiftRegister74HC595 shifter1 (2, 11, 9, 10);
  61. //time
  62. //--------------------------------------------------------------------------------------------------------------
  63. #include <TimeLib.h>
  64. #include <Wire.h>
  65. #include <DS1307RTC.h>
  66. //start LCD
  67. //--------------------------------------------------------------------------------------------------------------
  68. #include <LiquidCrystal_I2C.h>
  69. // set the LCD address to 0x3F for a 20 chars 4 line display
  70. // Set the pins on the I2C chip used for LCD connections:
  71. // addr, en,rw,rs,d4,d5,d6,d7,bl,blpol
  72. LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
  73. //--------------------------------------------------------------------------------------------------------------
  74. void setup() {
  75. //power LED RG
  76. pinMode(24, OUTPUT);
  77. pinMode(25, OUTPUT);
  78. digitalWrite(25, HIGH);
  79. setSyncProvider(RTC.get);
  80. // start scene
  81. //--------------------------------------------------------------------------------------------------------------
  82. lcd.begin(20, 4);
  83. lcd.clear();
  84. lcd.setCursor(0, 0);
  85. lcd.print("Arduino MIDI");
  86. lcd.setCursor(0, 1);
  87. lcd.print("Controller Load ");
  88. // encoder LED graph start
  89. //--------------------------------------------------------------------------------------------------------------
  90. // for (int i = 0; i < 9; i++) {
  91. // for (int i1 = 0; i1 < encoders; i1++) {
  92. // shifterset(i, i1);
  93. // }
  94. // delay(1);
  95. // }
  96. // for (int i = 8; i > -1; i--) {
  97. // for (int i1 = 0; i1 < encoders; i1++) {
  98. // shifterset(i, i1);
  99. // }
  100. // delay(1);
  101. // }
  102. // delay(100);
  103. for (int i = 0; i < 5; i++) {
  104. shifter0.setAllHigh();
  105. shifter1.setAllHigh();
  106. delay(250);
  107. shifter0.setAllLow();
  108. shifter1.setAllLow();
  109. delay(250);
  110. }
  111. //encoder start
  112. //--------------------------------------------------------------------------------------------------------------
  113. for (int i = 0; i < encoders; i++) {
  114. led[i] = map(encoderPosCount[i], 0, 127, 0, 8);
  115. shifterset(led[i], i);
  116. }
  117. //fine adjust
  118. //--------------------------------------------------------------------------------------------------------------
  119. pinMode(23, OUTPUT);
  120. pinMode(22, INPUT);
  121. //74HC165 setup
  122. //--------------------------------------------------------------------------------------------------------------
  123. /* Initialize our digital pins...
  124. */
  125. pinMode(ploadPin, OUTPUT);
  126. pinMode(clockEnablePin, OUTPUT);
  127. pinMode(clockPin, OUTPUT);
  128. pinMode(dataPin, INPUT);
  129. digitalWrite(clockPin, LOW);
  130. digitalWrite(ploadPin, HIGH);
  131. /* Read in and display the pin states at startup.
  132. */
  133. read_shift_regs();
  134. display_pin_values();
  135. //set display
  136. //--------------------------------------------------------------------------------------------------------------
  137. Serial1.begin(31250);
  138. Serial.begin(115200);
  139. delay(500);
  140. lcd.clear();
  141. timedate();
  142. lcd.setCursor(2, 2);
  143. lcd.print("OUT: 000 CH: 000");
  144. lcd.setCursor(2, 3);
  145. lcd.print("IN: 000 CH: 000");
  146. digitalWrite(25, LOW);
  147. digitalWrite(24, HIGH);
  148. }
  149. //setup ende
  150. //--------------------------------------------------------------------------------------------------------------
  151. void loop() {
  152. //74HC165 read
  153. read_shift_regs();
  154. /* If there was a chage in state, display which ones changed.
  155. */
  156. for (int i = 0; i < DATA_WIDTH; i++) {
  157. if (shift[i] != shift_old[i])
  158. {
  159. display_pin_values();
  160. shift_old[i] = shift[i];
  161. }
  162. }
  163. readdata(); // Midi data read
  164. encoder(); // read encoder pos and send Midi data
  165. button(); // read button state and send Midi data
  166. if (millis() > millisold) {
  167. timedate();
  168. millisold = millis() + 10000;
  169. }
  170. //fine adjust
  171. adjust = digitalRead(22);
  172. if (adjust == HIGH && adjustold == LOW) {
  173. digitalWrite(23, HIGH);
  174. if (adjuststate == 1) {
  175. adjuststate = 0;
  176. digitalWrite(23, LOW);
  177. } else {
  178. adjuststate = 1;
  179. }
  180. adjustold = adjust;
  181. }
  182. if (adjust == LOW && adjustold == HIGH) {
  183. adjustold = adjust;
  184. }
  185. }
  186. // midi send data
  187. //--------------------------------------------------------------------------------------------------------------
  188. void MIDISEND(int controlChange, int controllerNummer, int controllerWert) {
  189. Serial1.write(controlChange);
  190. Serial1.write(controllerNummer);
  191. Serial1.write(controllerWert);
  192. setout(controllerWert, controllerNummer);
  193. }
  194. // Midi read data
  195. //--------------------------------------------------------------------------------------------------------------
  196. void readdata() {
  197. if (Serial1.available() > 2) {
  198. commandByte = Serial1.read();//read first byte
  199. noteByte = Serial1.read();//read next byte Channel 1-127
  200. velocityByte = Serial1.read();//read final byte value 0-127
  201. setin(velocityByte, noteByte);
  202. if (commandByte == noteOn) { //if note on message
  203. if (noteByte < 20) {
  204. //encoders
  205. for (int i = 0; i < encoders; i++) {
  206. int encodernum = i + 1;
  207. if (noteByte == encodernum) {
  208. encoderPosCount[i] = velocityByte;
  209. led[i] = map(velocityByte, 0, 127, 0, 8);
  210. shifterset(led[i], i);
  211. }
  212. }
  213. } else {
  214. // buttons
  215. for (int i = 0; i < buttons; i++) {
  216. if (noteByte == ButtonChannel[i]) {
  217. if (velocityByte == 127) {
  218. shifter1.set(i, HIGH); //turn on led
  219. } else {
  220. shifter1.set(i, LOW); //turn on led
  221. }
  222. }
  223. }
  224. }
  225. }
  226. }
  227. }
  228. // button config
  229. //--------------------------------------------------------------------------------------------------------------
  230. void button() {
  231. for (int i = 0; i < buttons; i++) {
  232. if (taste[i] == HIGH && tasteAlt[i] == LOW) {
  233. shifter1.set(i, HIGH);
  234. MIDISEND(noteOn, ButtonChannel[i], 127);
  235. tasteAlt[i] = taste[i];
  236. }
  237. if (taste[i] == LOW && tasteAlt[i] == HIGH) {
  238. shifter1.set(i, LOW);
  239. MIDISEND(noteOn, ButtonChannel[i], 0);
  240. tasteAlt[i] = taste[i];
  241. }
  242. }
  243. }
  244. // encoder config
  245. //--------------------------------------------------------------------------------------------------------------
  246. void encoder() {
  247. for (int e_num = 0; e_num < encoders; e_num++) {
  248. aVal[e_num] = pinA[e_num];
  249. if (aVal[e_num] != pinALast[e_num]) { // Means the knob is rotating
  250. // if the knob is rotating, we need to determine direction
  251. // We do that by reading pin B.
  252. if (pinB[e_num] != aVal[e_num]) { // Means pin A Changed first - We're Rotating Clockwise
  253. if (encoderPosCount[e_num] < 127) {
  254. if (adjuststate == 0) {
  255. encoderPosCount[e_num] = encoderPosCount[e_num] + 2;
  256. } else {
  257. encoderPosCount[e_num] = encoderPosCount[e_num] + 1;
  258. }
  259. if ( encoderPosCount[e_num] > 127) {
  260. encoderPosCount[e_num] = 127;
  261. }
  262. MIDISEND(noteOn, EncoderChannel[e_num], encoderPosCount[e_num]);
  263. led[e_num] = map(encoderPosCount[e_num], 0, 127, 0, 8);
  264. shifterset(led[e_num], e_num);
  265. }
  266. } else {// Otherwise B changed first and we're moving CCW
  267. if (encoderPosCount[e_num] > 0) {
  268. if (adjuststate == 0) {
  269. encoderPosCount[e_num] = encoderPosCount[e_num] - 2;
  270. } else {
  271. encoderPosCount[e_num] = encoderPosCount[e_num] - 1;
  272. }
  273. if ( encoderPosCount[e_num] < 0) {
  274. encoderPosCount[e_num] = 0;
  275. }
  276. MIDISEND(noteOn, EncoderChannel[e_num], encoderPosCount[e_num]);
  277. led[e_num] = map(encoderPosCount[e_num], 0, 127, 0, 8);
  278. shifterset(led[e_num], e_num);
  279. }
  280. }
  281. }
  282. pinALast[e_num] = aVal[e_num];
  283. }
  284. }
  285. //time date
  286. //--------------------------------------------------------------------------------------------------------------
  287. void timedate() {
  288. lcd.setCursor(0, 0);
  289. if (day() < 10) {
  290. lcd.print("0");
  291. lcd.print(day());
  292. } else {
  293. lcd.print(day());
  294. }
  295. lcd.print(".");
  296. lcd.setCursor(3, 0);
  297. if (month() < 10) {
  298. lcd.print("0");
  299. lcd.print(month());
  300. } else {
  301. lcd.print(month());
  302. }
  303. lcd.print(".");
  304. if (year() < 10) {
  305. lcd.print("0");
  306. lcd.print(year());
  307. } else {
  308. lcd.print(year());
  309. }
  310. lcd.setCursor(15, 0);
  311. if (hour() < 10) {
  312. lcd.print("0");
  313. lcd.print(hour());
  314. } else {
  315. lcd.print(hour());
  316. }
  317. lcd.print(":");
  318. if (minute() < 10) {
  319. lcd.print("0");
  320. lcd.print(minute());
  321. } else {
  322. lcd.print(minute());
  323. }
  324. }
  325. //display out
  326. //--------------------------------------------------------------------------------------------------------------
  327. void setout (int wert, int chan) {
  328. lcd.setCursor(7, 2);
  329. if (wert < 10) {
  330. lcd.print("00");
  331. lcd.print(wert);
  332. } else if (wert < 100) {
  333. lcd.print("0");
  334. lcd.print(wert);
  335. } else {
  336. lcd.print(wert);
  337. }
  338. lcd.setCursor(15, 2);
  339. if (chan < 10) {
  340. lcd.print("00");
  341. lcd.print(chan);
  342. } else if (chan < 100) {
  343. lcd.print("0");
  344. lcd.print(chan);
  345. } else {
  346. lcd.print(chan);
  347. }
  348. }
  349. //set input display
  350. //--------------------------------------------------------------------------------------------------------------
  351. void setin (int wert, int chan) {
  352. lcd.setCursor(7, 3);
  353. if (wert < 10) {
  354. lcd.print("00");
  355. lcd.print(wert);
  356. } else if (wert < 100) {
  357. lcd.print("0");
  358. lcd.print(wert);
  359. } else {
  360. lcd.print(wert);
  361. }
  362. lcd.setCursor(15, 3);
  363. if (chan < 10) {
  364. lcd.print("00");
  365. lcd.print(chan);
  366. } else if (chan < 100) {
  367. lcd.print("0");
  368. lcd.print(chan);
  369. } else {
  370. lcd.print(chan);
  371. }
  372. }
  373. //set encoder shift
  374. //--------------------------------------------------------------------------------------------------------------
  375. void shifterset(int ledval, int shifternum) {
  376. int ledout = ledval;
  377. int start = shifternum * 8;
  378. for (int i = 0; i < shifternum; i++) {
  379. ledout = ledout + 8;
  380. }
  381. for (int i = start; i < ledout; i++) {
  382. shifter0.set(i, HIGH);
  383. }
  384. if (led_state_old[shifternum] > ledout) {
  385. for (int i = ledout; i < led_state_old[shifternum]; i++) {
  386. shifter0.set(i, LOW);
  387. }
  388. }
  389. led_state_old[shifternum] = ledout;
  390. }
  391. //74HC165 funktion
  392. //--------------------------------------------------------------------------------------------------------------
  393. void read_shift_regs()
  394. {
  395. int bitVal;
  396. /* Trigger a parallel Load to latch the state of the data lines,
  397. */
  398. digitalWrite(clockEnablePin, HIGH);
  399. digitalWrite(ploadPin, LOW);
  400. delayMicroseconds(PULSE_WIDTH_USEC);
  401. digitalWrite(ploadPin, HIGH);
  402. digitalWrite(clockEnablePin, LOW);
  403. /* Loop to read each bit value from the serial out line
  404. * of the SN74HC165N.
  405. */
  406. for (int i = 0; i < DATA_WIDTH; i++)
  407. {
  408. bitVal = digitalRead(dataPin);
  409. /* Set the corresponding bit in bytesVal.
  410. */
  411. shift[DATA_WIDTH - 1 - i] = bitVal;
  412. /* Pulse the Clock (rising edge shifts the next bit).
  413. */
  414. digitalWrite(clockPin, HIGH);
  415. delayMicroseconds(PULSE_WIDTH_USEC);
  416. digitalWrite(clockPin, LOW);
  417. }
  418. }
  419. //--------------------------------------------------------------------------------------------------------------
  420. /* Dump the list of zones along with their current status.
  421. */
  422. void display_pin_values()
  423. {
  424. countA = 0;
  425. for (int i = 0; i < DATA_WIDTH; i++)
  426. {
  427. if (shift[i] == 1) {
  428. data = HIGH;
  429. } else {
  430. data = LOW;
  431. }
  432. Serial.print("Pin: ");
  433. Serial.print(i);
  434. Serial.print(" ");
  435. Serial.print(data);
  436. Serial.println();
  437. if (i < encodernums) {
  438. if (count == 0) {
  439. pinA[countA / 2] = data;
  440. count = 1;
  441. } else {
  442. pinB[countA / 2] = data;
  443. count = 0;
  444. }
  445. countA++;
  446. } else {
  447. if (i == encodernums) {
  448. countA = 0;
  449. Serial.print("BUTTONS");
  450. Serial.println();
  451. }
  452. if (countA < buttons) {
  453. taste[countA] = data;
  454. countA++;
  455. }
  456. }
  457. }
  458. }