Advertisement
smias555

Untitled

May 1st, 2025
43
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 19.22 KB | None | 0 0
  1. // SPDX-FileCopyrightText: 2019 Erin St. Blaine for Adafruit Industries
  2. // SPDX-FileCopyrightText: 2019 John Edgar Park for Adafruit Industries
  3. //
  4. // SPDX-License-Identifier: MIT
  5. //
  6. //Ada_remoteFXTrigger_NeoTrellis_TX
  7. //Remote Effects Trigger Box Transmitter
  8. //by John Park
  9. // & Erin St. Blaine
  10. //for Adafruit Industries
  11.  
  12. // General purpose button box
  13. // for triggering remote effects
  14. // using packet radio Feather boards
  15. //
  16. //
  17. //MIT License
  18.  
  19. #include <SPI.h>
  20. #include <RH_RF69.h>
  21. #include <Wire.h>
  22. #include <Adafruit_GFX.h>
  23. #include <Adafruit_SSD1306.h>
  24. #include <Adafruit_NeoTrellis.h>
  25.  
  26. #include <Encoder.h>
  27. int m = 0; //variable to increment through menu list
  28. int x = 17; //variable for referencing buttons -- setting X to a non-existent button
  29. /********* Encoder Setup ***************/
  30. #define PIN_ENCODER_SWITCH 11
  31. Encoder knob(10, 12);
  32. uint8_t activeRow = 0;
  33. long pos = -999;
  34. long newpos;
  35. int prevButtonState = HIGH;
  36. bool needsRefresh = true;
  37. bool advanced = false;
  38. unsigned long startTime;
  39.  
  40.  
  41. /********* NeoTrellis Setup ***************/
  42. Adafruit_NeoTrellis trellis;
  43.  
  44. #define MOMENTARY 0
  45. #define LATCHING 1
  46. #define MODE LATCHING //all Trellis buttons in latching mode
  47. #define NUMTRELLIS 1
  48. #define numKeys (NUMTRELLIS * 16)
  49. #define INTPIN A2
  50. int NUM_SCREENS = 3; // change this number to add more screens
  51. #define RFM69_CS 10 // Chip Select
  52. #define RFM69_INT 9 // Interrupt pin
  53. #define RFM69_RST 6 // Reset pin
  54.  
  55.  
  56. //define a callback for key presses
  57. TrellisCallback blink(keyEvent evt){
  58. // Check is the pad pressed?
  59. if (evt.bit.EDGE == SEESAW_KEYPAD_EDGE_RISING) {
  60. //trellis.pixels.setPixelColor(evt.bit.NUM, 0xFFFFFF); //on rising
  61. } else if (evt.bit.EDGE == SEESAW_KEYPAD_EDGE_FALLING) {
  62. // or is the pad released?
  63. //trellis.pixels.setPixelColor(m, Wheel(map(m*2, 0, trellis.pixels.numPixels(), 0, 255))); //off falling
  64. x = evt.bit.NUM;
  65. }
  66.  
  67. // Turn on/off the neopixels!
  68. trellis.pixels.show();
  69.  
  70. return 0;
  71. }
  72.  
  73.  
  74.  
  75. /************ OLED Setup ***************/
  76. Adafruit_SSD1306 oled = Adafruit_SSD1306();
  77. #if defined(ESP8266)
  78. #define BUTTON_A 0
  79. #define BUTTON_B 16
  80. #define BUTTON_C 2
  81. #define LED 0
  82. #elif defined(ESP32)
  83. #define BUTTON_A 15
  84. #define BUTTON_B 32
  85. #define BUTTON_C 14
  86. #define LED 13
  87. #elif defined(ARDUINO_STM32F2_FEATHER)
  88. #define BUTTON_A PA15
  89. #define BUTTON_B PC7
  90. #define BUTTON_C PC5
  91. #define LED PB5
  92. #elif defined(TEENSYDUINO)
  93. #define BUTTON_A 4
  94. #define BUTTON_B 3
  95. #define BUTTON_C 8
  96. #define LED 13
  97. #elif defined(ARDUINO_FEATHER52)
  98. #define BUTTON_A 31
  99. #define BUTTON_B 30
  100. #define BUTTON_C 27
  101. #define LED 17
  102. #else // 32u4, M0, and 328p
  103. #define BUTTON_A 9
  104. #define BUTTON_B 6
  105. #define BUTTON_C 5
  106. #define LED 13
  107. #endif
  108.  
  109.  
  110. /************ Radio Setup ***************/
  111. // Can be changed to 434.0 or other frequency, must match RX's freq!
  112. #define RF69_FREQ 915.0
  113.  
  114. #if defined (__AVR_ATmega32U4__) // Feather 32u4 w/Radio
  115. #define RFM69_CS 8
  116. #define RFM69_INT 7
  117. #define RFM69_RST 4
  118. #endif
  119.  
  120. #if defined(ARDUINO_SAMD_FEATHER_M0) // Feather M0 w/Radio
  121. #define RFM69_CS 8
  122. #define RFM69_INT 3
  123. #define RFM69_RST 4
  124. #endif
  125.  
  126. #if defined (__AVR_ATmega328P__) // Feather 328P w/wing
  127. #define RFM69_INT 3 //
  128. #define RFM69_CS 4 //
  129. #define RFM69_RST 2 // "A"
  130. #endif
  131.  
  132. #if defined(ESP32) // ESP32 feather w/wing
  133. #define RFM69_RST 13 // same as LED
  134. #define RFM69_CS 33 // "B"
  135. #define RFM69_INT 27 // "A"
  136. #endif
  137.  
  138.  
  139. // Singleton instance of the radio driver
  140. RH_RF69 rf69(RFM69_CS, RFM69_INT);
  141.  
  142. int lastButton=17; //last button pressed for Trellis logic
  143.  
  144. int menuList[8]={1,2,3,4,5,6,7,8}; //for rotary encoder choices
  145. //int m = 0; //variable to increment through menu list
  146. int lastTB[8] = {16, 16, 16, 16, 16, 16, 16, 16}; //array to store per-menu Trellis button
  147.  
  148.  
  149. /*******************SETUP************/
  150. void setup() {
  151. delay(500);
  152. Serial.begin(115200);
  153. //while (!Serial) { delay(1); } // wait until serial console is open,
  154. //remove if not tethered to computer
  155.  
  156. pinMode(PIN_ENCODER_SWITCH, INPUT_PULLUP);//set encoder push switch pin to input pullup
  157. pinMode(INTPIN, INPUT);
  158.  
  159. //digitalPinToInterrupt(10); //on M0, Encoder library doesn't auto set these as interrupts
  160. //digitalPinToInterrupt(12);
  161.  
  162. // Initialize OLED display
  163. oled.begin(SSD1306_SWITCHCAPVCC, 0x3C); // initialize with the I2C addr 0x3C (for the 128x32)
  164. oled.setTextWrap(false);
  165. oled.display();
  166. delay(500);
  167. oled.clearDisplay();
  168. oled.display();
  169. oled.setTextSize(2);
  170. oled.setTextColor(WHITE);
  171. pinMode(BUTTON_A, INPUT_PULLUP);
  172. pinMode(BUTTON_B, INPUT_PULLUP);
  173. pinMode(BUTTON_C, INPUT_PULLUP);
  174. pinMode(LED, OUTPUT);
  175. pinMode(RFM69_RST, OUTPUT);
  176. digitalWrite(RFM69_RST, LOW);
  177.  
  178. // manual reset
  179. digitalWrite(RFM69_RST, HIGH);
  180. delay(10);
  181. digitalWrite(RFM69_RST, LOW);
  182. delay(10);
  183.  
  184. if (!rf69.init()) {
  185. Serial.println("RFM69 radio init failed");
  186. while (1);
  187. }
  188. Serial.println("RFM69 radio init OK!");
  189.  
  190. // Defaults after init are 434.0MHz, modulation GFSK_Rb250Fd250, +13dbM (for low power module)
  191. // No encryption
  192. if (!rf69.setFrequency(RF69_FREQ)) {
  193. Serial.println("setFrequency failed");
  194. }
  195.  
  196. // If you are using a high power RF69 eg RFM69HW, you *must* set a Tx power with the
  197. // ishighpowermodule flag set like this:
  198. rf69.setTxPower(14, true);
  199.  
  200. // The encryption key has to be the same as the one in the server
  201. uint8_t key[] = { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08,
  202. 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08};
  203. rf69.setEncryptionKey(key);
  204.  
  205. pinMode(LED, OUTPUT);
  206.  
  207. Serial.print("RFM69 radio @"); Serial.print((int)RF69_FREQ); Serial.println(" MHz");
  208.  
  209. oled.setCursor(0,0);
  210. oled.println("RFM69 @ ");
  211. oled.print((int)RF69_FREQ);
  212. oled.println(" MHz");
  213. oled.display();
  214. delay(1200); //pause to let freq message be read by a human
  215.  
  216. oled.clearDisplay();
  217. oled.setCursor(0,0);
  218. oled.println("REMOTE FX");
  219. oled.setCursor(0,16);
  220. oled.println("TRIGGER");
  221. oled.display();
  222.  
  223. if (!trellis.begin()) {
  224. Serial.println("Could not start trellis, check wiring?");
  225. while(1);
  226. } else {
  227. Serial.println("NeoPixel Trellis started");
  228. }
  229.  
  230. //activate all NeoTrellis keys and set callbacks
  231. for(int i=0; i<NEO_TRELLIS_NUM_KEYS; i++){
  232. trellis.activateKey(i, SEESAW_KEYPAD_EDGE_RISING);
  233. trellis.activateKey(i, SEESAW_KEYPAD_EDGE_FALLING);
  234. trellis.registerCallback(i, blink);
  235. }
  236.  
  237. //do a little animation to show we're on
  238. for (uint16_t i=0; i<trellis.pixels.numPixels(); i++) {
  239. trellis.pixels.setPixelColor(i, Wheel(map(i, 0, trellis.pixels.numPixels(), 0, 255)));
  240. trellis.pixels.show();
  241. delay(50);
  242. }
  243. for (uint16_t i=0; i<trellis.pixels.numPixels(); i++) {
  244. trellis.pixels.setPixelColor(i, 0x000000);
  245. trellis.pixels.show();
  246. delay(50);
  247. }
  248.  
  249. }
  250.  
  251. //////////////////////////////////////////////////////////////////
  252. //////////////////////////////////////////////////////////////////
  253.  
  254. void loop() {
  255.  
  256.  
  257. /*************Rotary Encoder Menu***********/
  258.  
  259. //check the encoder knob, set the current position as origin
  260. long newpos = knob.read() / 4;//divide for encoder detents
  261.  
  262. /* // for debugging
  263. Serial.print("pos=");
  264. Serial.print(pos);
  265. Serial.print(", newpos=");
  266. Serial.println(newpos);
  267. */
  268.  
  269. if(newpos != pos){
  270. int diff = newpos - pos;//check the different between old and new position
  271. if(diff>=1){
  272. m++;
  273. m = (m+NUM_SCREENS) % NUM_SCREENS;//modulo to roll over the m variable through the list size
  274. }
  275.  
  276. if(diff==-1){ //rotating backwards
  277. m--;
  278. m = (m+NUM_SCREENS) % NUM_SCREENS;
  279. }
  280. /* //uncomment for debugging or general curiosity
  281. Serial.print("Diff = ");
  282. Serial.print(diff);
  283. Serial.print(" pos= ");
  284. Serial.print(pos);
  285. Serial.print(", newpos=");
  286. Serial.println(newpos);
  287. Serial.println(menuList[m]);
  288. */
  289.  
  290. pos = newpos;
  291.  
  292. // Serial.print("m is: ");
  293. //Serial.println(m);
  294. //write to the display
  295. oled.setCursor(0,3);
  296. oled.clearDisplay();
  297.  
  298. int p; //for drawing bullet point menu location pixels
  299. int q;
  300.  
  301. if (m==0){
  302. for(p=4;p<8;p++){
  303. for(q=0;q<4;q++){
  304. oled.drawPixel(q,p,WHITE);
  305. }
  306. }
  307. oled.print(" Solids");
  308. clearPixels();
  309. trellis.pixels.setPixelColor(0, 50,0,0);
  310. trellis.pixels.setPixelColor(1, 50,50,0);
  311. trellis.pixels.setPixelColor(2, 0,50,0);
  312. trellis.pixels.setPixelColor(3, 0,0,50);
  313. trellis.pixels.setPixelColor(4, 20,0,50);
  314. trellis.pixels.setPixelColor(5, 50,0,20);
  315. trellis.pixels.setPixelColor(6, 100,100,100);
  316. trellis.pixels.setPixelColor(7, 10,10,10);
  317. trellis.pixels.show();
  318. }
  319. if (m==1){
  320. for(p=8;p<12;p++){
  321. for(q=0;q<4;q++){
  322. oled.drawPixel(q,p,WHITE);
  323. }
  324. }
  325. oled.print(" Gradients");
  326. clearPixels();
  327. trellis.pixels.setPixelColor(0, 50,0,0);
  328. trellis.pixels.setPixelColor(1, 50,50,0);
  329. trellis.pixels.setPixelColor(2, 0,50,0);
  330. trellis.pixels.setPixelColor(3, 0,0,50);
  331. trellis.pixels.setPixelColor(4, 20,0,50);
  332. trellis.pixels.setPixelColor(5, 50,0,20);
  333. trellis.pixels.setPixelColor(6, 100,100,100);
  334. trellis.pixels.setPixelColor(7, 10,10,10);
  335. trellis.pixels.show();
  336. }
  337. if (m==2){
  338. for(p=12;p<16;p++){
  339. for(q=0;q<4;q++){
  340. oled.drawPixel(q,p,WHITE);
  341. }
  342. }
  343. oled.print(" Rainbows");
  344. clearPixels();
  345. trellis.pixels.setPixelColor(0, 50,0,0);
  346. trellis.pixels.setPixelColor(1, 50,50,0);
  347. trellis.pixels.setPixelColor(2, 0,50,0);
  348. trellis.pixels.setPixelColor(7, 10,10,10);
  349. trellis.pixels.show();
  350. }
  351.  
  352.  
  353.  
  354. oled.display();
  355. }
  356.  
  357. char radiopacket[20];
  358.  
  359.  
  360. /**************Solids**************/
  361.  
  362. if(m==0){ //next menu item
  363.  
  364. if (x==0){ //button 1 sends button A command
  365. radiopacket[0] = 'A';
  366. oled.clearDisplay();
  367. oled.setCursor(0,0);
  368. oled.print("Solid");
  369. oled.setCursor(50,16);
  370. oled.print("RED");
  371. oled.display();
  372. }
  373. if (x==1){ //button 2 sends button B command
  374. radiopacket[0] = 'B';
  375. oled.clearDisplay();
  376. oled.setCursor(0,0);
  377. oled.print("Solid");
  378. oled.setCursor(50,16);
  379. oled.print("GOLD");
  380. oled.display();
  381. }
  382. if (x==2){ //button 3 sends button C command
  383. radiopacket[0] = 'C';
  384. oled.clearDisplay();
  385. oled.setCursor(0,0);
  386. oled.print("Solid");
  387. oled.setCursor(50,16);
  388. oled.print("GREEN");
  389. oled.display();
  390. }
  391.  
  392. if (x==3){ //button 4 sends button D command
  393. radiopacket[0] = 'D';
  394. oled.clearDisplay();
  395. oled.setCursor(0,0);
  396. oled.print("Solid");
  397. oled.setCursor(50,16);
  398. oled.print("BLUE");
  399. oled.display();
  400. }
  401.  
  402. if (x==4){ //button 5 sends button E command
  403. radiopacket[0] = 'E';
  404. oled.clearDisplay();
  405. oled.setCursor(0,0);
  406. oled.print("Solid");
  407. oled.setCursor(50,16);
  408. oled.print("PURPLE");
  409. oled.display();
  410. }
  411. if (x==5){ //button 6 sends button F command
  412. radiopacket[0] = 'F';
  413. oled.clearDisplay();
  414. oled.setCursor(0,0);
  415. oled.print("Solid");
  416. oled.setCursor(50,16);
  417. oled.print("PINK");
  418. oled.display();
  419. }
  420. if (x==6){ //button 7 sends button G command
  421. radiopacket[0] = 'G';
  422. oled.clearDisplay();
  423. oled.setCursor(0,0);
  424. oled.print("Solid");
  425. oled.setCursor(50,16);
  426. oled.print("WHITE");
  427. oled.display();
  428. }
  429.  
  430. if (x==7){ //button 8 sends button H command
  431. radiopacket[0] = 'H';
  432. oled.clearDisplay();
  433. oled.setCursor(0,0);
  434. oled.print("Solid");
  435. oled.setCursor(50,16);
  436. oled.print("OFF");
  437. oled.display();
  438. }
  439.  
  440.  
  441. trellis.pixels.show(); // tell the trellis to set the LEDs we requested
  442. }
  443.  
  444. /**************Gradients**************/
  445.  
  446. if(m==1){ //next menu item
  447.  
  448. if (x==0){ //button 1 sends button A command
  449. radiopacket[0] = 'I';
  450. oled.clearDisplay();
  451. oled.setCursor(0,0);
  452. oled.print("Gradient");
  453. oled.setCursor(50,16);
  454. oled.print("RED");
  455. oled.display();
  456. }
  457. if (x==1){ //button 2 sends button B command
  458. radiopacket[0] = 'J';
  459. oled.clearDisplay();
  460. oled.setCursor(0,0);
  461. oled.print("Gradient");
  462. oled.setCursor(50,16);
  463. oled.print("GOLD");
  464. oled.display();
  465. }
  466. if (x==2){ //button 3 sends button C command
  467. radiopacket[0] = 'K';
  468. oled.clearDisplay();
  469. oled.setCursor(0,0);
  470. oled.print("Gradient");
  471. oled.setCursor(50,16);
  472. oled.print("GREEN");
  473. oled.display();
  474. }
  475.  
  476. if (x==3){ //button 4 sends button D command
  477. radiopacket[0] = 'L';
  478. oled.clearDisplay();
  479. oled.setCursor(0,0);
  480. oled.print("Gradient");
  481. oled.setCursor(50,16);
  482. oled.print("BLUE");
  483. oled.display();
  484. }
  485.  
  486. if (x==4){ //button 5 sends button E command
  487. radiopacket[0] = 'M';
  488. oled.clearDisplay();
  489. oled.setCursor(0,0);
  490. oled.print("Gradient");
  491. oled.setCursor(50,16);
  492. oled.print("PURPLE");
  493. oled.display();
  494. }
  495. if (x==5){ //button 6 sends button F command
  496. radiopacket[0] = 'N';
  497. oled.clearDisplay();
  498. oled.setCursor(0,0);
  499. oled.print("Gradient");
  500. oled.setCursor(50,16);
  501. oled.print("PINK");
  502. oled.display();
  503. }
  504. if (x==6){ //button 7 sends button G command
  505. radiopacket[0] = 'O';
  506. oled.clearDisplay();
  507. oled.setCursor(0,0);
  508. oled.print("Gradient");
  509. oled.setCursor(50,16);
  510. oled.print("WHITE");
  511. oled.display();
  512. }
  513.  
  514. if (x==7){ //button 8 sends button H command
  515. radiopacket[0] = 'H';
  516. oled.clearDisplay();
  517. oled.setCursor(0,0);
  518. oled.print("Gradient");
  519. oled.setCursor(50,16);
  520. oled.print("OFF");
  521. oled.display();
  522. }
  523. trellis.pixels.show(); // tell the trellis to set the LEDs we requested
  524. }
  525.  
  526.  
  527. /**************Rainbows**************/
  528.  
  529. if(m==2){ //next menu item
  530.  
  531. if (x==0){ //button 1 sends button A command
  532. radiopacket[0] = 'P';
  533. oled.clearDisplay();
  534. oled.setCursor(0,0);
  535. oled.print("Rainbow");
  536. oled.setCursor(50,16);
  537. oled.print("FADE");
  538. oled.display();
  539. }
  540. if (x==1){ //button 2 sends button B command
  541. radiopacket[0] = 'Q';
  542. oled.clearDisplay();
  543. oled.setCursor(0,0);
  544. oled.print("Rainbow");
  545. oled.setCursor(50,16);
  546. oled.print("SOFT");
  547. oled.display();
  548. }
  549. if (x==2){ //button 3 sends button C command
  550. radiopacket[0] = 'R';
  551. oled.clearDisplay();
  552. oled.setCursor(0,0);
  553. oled.print("Rainbow");
  554. oled.setCursor(50,16);
  555. oled.print("TWINKLE");
  556. oled.display();
  557. }
  558.  
  559. if (x==7){ //button 8 sends button H command
  560. radiopacket[0] = 'H';
  561. oled.clearDisplay();
  562. oled.setCursor(0,0);
  563. oled.print("Rainbow");
  564. oled.setCursor(50,16);
  565. oled.print("OFF");
  566. oled.display();
  567. }
  568. trellis.pixels.show(); // tell the trellis to set the LEDs we requested
  569. }
  570.  
  571.  
  572.  
  573. Serial.print("Sending ");
  574. Serial.println(radiopacket[0]);
  575.  
  576. rf69.send((uint8_t *)radiopacket, strlen(radiopacket));
  577. rf69.waitPacketSent();
  578. //reset packet so unassigned buttons don't send last command
  579. radiopacket[0]='Z'; //also being used to turn off NeoPixels
  580. //from any unused button
  581.  
  582. if (rf69.waitAvailableTimeout(1000)) {
  583. // Should be a message for us now
  584. uint8_t buf[RH_RF69_MAX_MESSAGE_LEN];
  585. uint8_t len = sizeof(buf);
  586.  
  587. if (! rf69.recv(buf, &len)) {
  588. Serial.println("Receive failed");
  589. return;
  590. }
  591. digitalWrite(LED, HIGH);
  592. rf69.printBuffer("Received: ", buf, len);
  593. buf[len] = 0;
  594.  
  595. //Serial.print("TX Got: ");
  596. //Serial.println((char*)buf);
  597. Serial.print("RSSI: ");
  598. Serial.println(rf69.lastRssi(), DEC);
  599.  
  600. //delay(1000);//chill for a moment before returning the message to RX unit
  601.  
  602. /*************Reply message from RX unit***********/
  603. //oled.clearDisplay();
  604. //oled.print((char*)buf[0]);
  605. //oled.print("RSSI: "); oled.print(rf69.lastRssi());
  606. //oled.display();
  607.  
  608.  
  609. digitalWrite(LED, LOW);
  610. }
  611.  
  612. //lastButton=i;//set for next pass through to turn this one off
  613.  
  614.  
  615. trellis.read();
  616. delay(100); //the NeoTrellis has a resolution of around 60hz
  617.  
  618. }
  619.  
  620.  
  621. /******************************************/
  622.  
  623. // Input a value 0 to 255 to get a color value.
  624. // The colors are a transition r - g - b - back to r.
  625. uint32_t Wheel(byte WheelPos) {
  626. if(WheelPos < 85) {
  627. return trellis.pixels.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
  628. } else if(WheelPos < 170) {
  629. WheelPos -= 85;
  630. return trellis.pixels.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  631. } else {
  632. WheelPos -= 170;
  633. return trellis.pixels.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  634. }
  635. return 0;
  636. }
  637.  
  638. void clearPixels() {
  639. for (uint16_t i=0; i<trellis.pixels.numPixels(); i++) {
  640. trellis.pixels.setPixelColor(i, 0x000000);
  641. trellis.pixels.show();
  642. delay(2);
  643. }
  644. }
  645.  
  646.  
  647.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement