├── .gitignore ├── Digispark └── README.md ├── ESP8266 ├── MAX7219 │ ├── Scrolling_Text_From_Web_And_Youtube_Counter │ │ ├── MAX7219_8x8_Schematic.png │ │ ├── MAX7219_Scrolling_Sub_Counter.ino │ │ └── readme.md │ └── readme.md ├── OTA_Examples │ ├── OTA_LED_Flasher.ino │ ├── OTA_Minimal.ino │ └── readme.md ├── SHT21_ESP8266_UART_Out │ ├── SHT21_ESP8266_UART_Out.ino │ └── readme.md ├── Simple_Web_Server │ ├── Basic_Web_Server_1.ino │ ├── Basic_Web_Server_2.ino │ ├── WebServer_Schematic.jpg │ └── readme.md ├── YoutubeSubCounter_7Seg_WEMOS │ ├── 7Seg_Sub_Counter_Schematic.jpg │ ├── Sub_Counter_7seg.ino │ └── readme.md ├── YoutubeSubscriberCounter │ ├── SubCounter_Schematic.jpg │ ├── YouTubeSubscriberCounter.ino │ └── readme.md └── readme.md ├── README.md ├── Teensy ├── AudioEffects │ ├── SDCardChorusTest │ │ ├── SDCardChorusTest.ino │ │ └── readme.md │ ├── SDCardFlangeTest │ │ ├── SDCardFlangeTest.ino │ │ └── readme.md │ ├── SDCardWavFilePlayerTest │ │ ├── SDCardWavFilePlayerTest.ino │ │ └── readme.md │ ├── Teensy_AudioShield_Wiring.jpg │ ├── Teensy_Audio_Schematic.jpg │ └── readme.md ├── AudioTest │ ├── AudioSampleCashregister.cpp │ ├── AudioSampleCashregister.h │ ├── AudioSampleGong.cpp │ ├── AudioSampleGong.h │ ├── AudioSampleHihat.cpp │ ├── AudioSampleHihat.h │ ├── AudioSampleKick.cpp │ ├── AudioSampleKick.h │ ├── AudioSampleSnare.cpp │ ├── AudioSampleSnare.h │ ├── AudioSampleTomtom.cpp │ ├── AudioSampleTomtom.h │ ├── AudioTest.ino │ └── readme.md ├── NES_To_USB │ ├── NES_To_USB.ino │ └── readme.md ├── SNES_To_USB │ ├── SNES_To_USB.ino │ └── readme.md ├── TeensyDemo │ ├── TeensyDemo.ino │ ├── TeensyDemo_Schematic.jpg │ └── readme.md ├── USB_HID_Mouse │ ├── USB_HID_MOUSE.ino │ └── readme.md └── readme.md └── Uno ├── ACS712_AC_DC ├── ACS712_AC_DC_Current_Meas.ino └── readme.md ├── AVR_High_Voltage_Fuse_Programmer ├── 12v switch.jpg ├── AVR_HV_Fuse_Programmer.ino ├── Digispark HVSP Interface.jpg ├── Fuse_HVP_Schematic.jpg ├── VCC and 12v Reset Turn On Traces.jpg └── readme.md ├── DHT22 ├── DHT22_16x2_LCD │ ├── DHT22 16x2 LCD Schematic.jpg │ ├── DHT22_16x2_LCD.ino │ └── readme.md ├── DHT22_Serial │ ├── DHT22_Serial.ino │ ├── DHT22_Serial_Schematic.jpg │ └── readme.md ├── TFT_480x320 │ ├── DHT22 TFT LCD Schematic.jpg │ ├── DHT22_TFT_LCD_Display1.ino │ ├── DHT22_TFT_LCD_Display2.ino │ ├── Display Images.jpg │ └── readme.md └── readme.md ├── DMX512 ├── DMXFade.ino ├── DMX_Manual_Control.ino ├── DMX_Schematic.jpg └── readme.md ├── DMX_Serial_Tx_Rx ├── DMX_Controller_Schematic.png ├── DMX_Receiver_Schematic.png ├── Manual_Controller_Demo │ ├── DMX_Controller.ino │ ├── DMX_Fixture_WS2812.ino │ ├── readme.md │ └── ws2812.h ├── WS2812B_60_Test │ ├── DMX_WS2812_Controller_Demo.ino │ ├── DMX_WS2812_Fixture_Demo.ino │ ├── readme.md │ └── ws2812.h └── readme.md ├── DS18B20_LCD ├── 1602_LCD_I2C_HelloWorld.ino ├── 1602_LCD_PINS_HelloWorld.ino ├── DS18B20_LCD.ino ├── DS18B20_LCD_BASIC.ino ├── DS18B20_LCD_Schematic.jpg └── readme.md ├── DS18B20_TFT_LCD ├── DS18B20 TFT LCD Schematic.jpg ├── DS18B20_TFT_LCD.ino └── readme.md ├── DS18B20_Temp_Sensor ├── DS18B20_Schematic.jpg ├── DS18B20_Serial_Monitor_Only.ino ├── DS18B20_Temp_Sensor_OLED.ino └── readme.md ├── I2C_Scanner ├── I2C_Scanner.ino └── readme.md ├── NeoPixel ├── Chaser.ino ├── NeoPixel_60_Schematic.jpg ├── NeoPixel_Basics.ino ├── NeoPixel_White_Test.ino └── readme.md ├── NeoPixel_Tiles ├── NeoPixel_Tile_Schematic.jpg ├── Tile_Test.ino └── readme.md ├── NixiePrint ├── NixiePrint.ino └── readme.md ├── Oscilloscope_XY_PWM_Tutorial ├── readme.md └── scope_XY_Test.ino ├── PCF8574 ├── PCF8574.ino └── readme.md ├── PCF8574_Relays ├── PCF8574_Relay_Control_ESP8266_Schematic.jpg ├── PCF8574_Relay_Control_Uno_Schematic.jpg ├── PCF8574_Relays.ino └── readme.md ├── RotaryJoystickMame ├── RotaryJoystickSchematic_3pin.jpg ├── RotaryJoystickSchematic_4pin.jpg ├── Rotary_Joystick_To_MAME_3pin.ino ├── Rotary_Joystick_To_MAME_4pin.ino └── readme.txt ├── SHT21_TFT_LCD ├── SHT21_Schematic.jpg ├── SHT21_TFT_LCD.ino └── readme.md ├── SSD1306_Soil_Meter ├── Capacitive Soil Probe OLED Schematic.jpg ├── SSD1306_Soil_Meter.ino ├── SSD1306_Soil_Meter_PWR_Save.ino └── readme.me ├── Serial_Plotter ├── Serial_Plotter.ino └── readme.md ├── Spectrum_Analyzer ├── SpectrumAnalyzerSchematic.jpg ├── Spectrum_Analyzer.ino └── readme.md ├── X9C_Button_Test ├── X9C_555_Osc_Control.ino ├── X9C_Button_Test.ino └── readme.md ├── X9C_OpAmp_Gain_Control ├── OpAmp_Gain_Schematic.jpg ├── X9C_OpAmp_AutoGain_Control.ino ├── X9C_OpAmp_Gain_Control.ino └── readme.mc └── readme.md /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | Uno/.DS_Store 3 | Uno/AVR_High_Voltage_Fuse_Programmer/.DS_Store 4 | -------------------------------------------------------------------------------- /Digispark/README.md: -------------------------------------------------------------------------------- 1 | # Digispark ATTiny85 2 | -------------------------------------------------------------------------------- /ESP8266/MAX7219/Scrolling_Text_From_Web_And_Youtube_Counter/MAX7219_8x8_Schematic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GadgetReboot/Arduino/adf95ad05b710d7a58421f86df913644a04948d4/ESP8266/MAX7219/Scrolling_Text_From_Web_And_Youtube_Counter/MAX7219_8x8_Schematic.png -------------------------------------------------------------------------------- /ESP8266/MAX7219/Scrolling_Text_From_Web_And_Youtube_Counter/readme.md: -------------------------------------------------------------------------------- 1 | Using the MAX7219 8x8 matrix LED panel to create a scrolling text sign. 2 | Youtube subscriber count is displayed along with optional text entered from a web IP 3 | with a web site served by ESP8266 4 | -------------------------------------------------------------------------------- /ESP8266/MAX7219/readme.md: -------------------------------------------------------------------------------- 1 | Using the MAX7219 to control various LED configurations 2 | -------------------------------------------------------------------------------- /ESP8266/OTA_Examples/OTA_LED_Flasher.ino: -------------------------------------------------------------------------------- 1 | // ESP8266 OTA Example 2 | // Target Hardware: esp8266 NodeMCU 3 | // 4 | // Uses the ArduinoOTA library (included with ESP8266 board support) to allow sketches 5 | // to support firmware updates over the air (WiFi). 6 | // This sketch flashes an LED to show how OTA works in conjunction with a sketch. 7 | // 8 | // NodeMCU I2C Pins 9 | // LED: D1 10 | // 11 | // Required libraries and board files: 12 | // esp8266 install from boards manager 13 | // 14 | // Gadget Reboot 15 | 16 | 17 | #include 18 | #include 19 | 20 | #define ledPin D1 // led to blink 21 | 22 | const char* ssid = "Your Network Name"; 23 | const char* password = "Your Network Password"; 24 | 25 | void setup() { 26 | Serial.begin(9600); 27 | 28 | // start with led OFF 29 | pinMode(ledPin, OUTPUT); 30 | digitalWrite(ledPin, LOW); 31 | 32 | // join WiFi network 33 | Serial.println(); 34 | Serial.println("Joining WiFI..."); 35 | WiFi.mode(WIFI_STA); 36 | WiFi.begin(ssid, password); 37 | 38 | while (WiFi.status() != WL_CONNECTED) { 39 | delay(500); 40 | Serial.print("."); 41 | } 42 | 43 | Serial.println(""); 44 | Serial.println("WiFi connected."); 45 | Serial.print("IP address: "); 46 | Serial.println(WiFi.localIP()); 47 | 48 | // Port defaults to 8266 49 | // ArduinoOTA.setPort(8266); 50 | 51 | // Hostname defaults to esp8266-[ChipID] 52 | ArduinoOTA.setHostname("GR-ESP8266"); 53 | 54 | // No authentication by default 55 | // ArduinoOTA.setPassword("admin"); 56 | 57 | ArduinoOTA.onStart([]() { 58 | String type; 59 | if (ArduinoOTA.getCommand() == U_FLASH) { 60 | type = "sketch"; 61 | } else { // U_SPIFFS 62 | type = "filesystem"; 63 | } 64 | 65 | // NOTE: if updating SPIFFS this would be the place to unmount SPIFFS using SPIFFS.end() 66 | Serial.println("Start updating " + type); 67 | }); 68 | 69 | ArduinoOTA.onEnd([]() { 70 | Serial.println("\nEnd"); 71 | }); 72 | 73 | ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) { 74 | Serial.printf("Progress: %u%%\r", (progress / (total / 100))); 75 | }); 76 | 77 | ArduinoOTA.onError([](ota_error_t error) { 78 | Serial.printf("Error[%u]: ", error); 79 | if (error == OTA_AUTH_ERROR) { 80 | Serial.println("Auth Failed"); 81 | } else if (error == OTA_BEGIN_ERROR) { 82 | Serial.println("Begin Failed"); 83 | } else if (error == OTA_CONNECT_ERROR) { 84 | Serial.println("Connect Failed"); 85 | } else if (error == OTA_RECEIVE_ERROR) { 86 | Serial.println("Receive Failed"); 87 | } else if (error == OTA_END_ERROR) { 88 | Serial.println("End Failed"); 89 | } 90 | }); 91 | 92 | // initialize OTA capability 93 | ArduinoOTA.begin(); 94 | } 95 | 96 | void loop() { 97 | // handle any OTA requests 98 | ArduinoOTA.handle(); 99 | 100 | // normal sketch code 101 | digitalWrite(ledPin, HIGH); 102 | delay(1000); 103 | digitalWrite(ledPin, LOW); 104 | delay(1000); 105 | } 106 | -------------------------------------------------------------------------------- /ESP8266/OTA_Examples/OTA_Minimal.ino: -------------------------------------------------------------------------------- 1 | // ESP8266 OTA Example 2 | // Target Hardware: esp8266 NodeMCU 3 | // 4 | // Uses the ArduinoOTA library (included with ESP8266 board support) to allow sketches 5 | // to support firmware updates over the air (WiFi). 6 | // 7 | // This sketch is a skeleton that does nothing but wait for an OTA update request. 8 | // Normal sketch code can be added to this to enable OTA functionality. 9 | // 10 | // NodeMCU I2C Pins 11 | // none 12 | // 13 | // Required libraries and board files: 14 | // esp8266 install from boards manager 15 | // 16 | // Gadget Reboot 17 | 18 | #include 19 | #include 20 | 21 | const char* ssid = "Your Network Name"; 22 | const char* password = "Your Network Password"; 23 | 24 | void setup() { 25 | 26 | Serial.begin(9600); 27 | 28 | // set WiFi to station mode and disconnect from an AP if previously connected 29 | WiFi.mode(WIFI_STA); 30 | WiFi.disconnect(); 31 | delay(100); 32 | 33 | // attempt to connect to WiFi network 34 | Serial.println(); 35 | Serial.print("Connecting to WiFi..."); 36 | WiFi.begin(ssid, password); 37 | while (WiFi.status() != WL_CONNECTED) { 38 | Serial.print("."); 39 | delay(500); 40 | } 41 | 42 | // show WiFi status in serial monitor 43 | Serial.println(""); 44 | Serial.println("WiFi connected."); 45 | Serial.print("IP address: "); 46 | Serial.println(WiFi.localIP()); 47 | 48 | ArduinoOTA.begin(); 49 | } 50 | 51 | void loop() { 52 | ArduinoOTA.handle(); 53 | // place code here 54 | } 55 | -------------------------------------------------------------------------------- /ESP8266/OTA_Examples/readme.md: -------------------------------------------------------------------------------- 1 | How to configure an ESP8266 sketch for basic OTA functionality to allow further updates over the air when joined on WiFi. 2 | -------------------------------------------------------------------------------- /ESP8266/SHT21_ESP8266_UART_Out/SHT21_ESP8266_UART_Out.ino: -------------------------------------------------------------------------------- 1 | /**************************************************************** 2 | SHT21 Temperature/Humidity Sensor Demo 3 | 4 | An example sketch that reads the sensor data and prints the 5 | temperature in degrees C and relative humidity %RH to the 6 | serial port. 7 | 8 | Data will appear in the serial monitor of the Arduino IDE and 9 | if an external UART is connected, data can be read and parsed 10 | on other hardware. 11 | 12 | Target hardware: ESP8266 13 | 14 | Gadget Reboot 15 | 16 | ***************************************************************/ 17 | 18 | #include 19 | #include "SHT21.h" 20 | 21 | SHT21 SHT21; 22 | 23 | void setup() { 24 | 25 | // initialize serial port and SHT21 sensor 26 | Serial.begin(9600); 27 | SHT21.begin(); 28 | 29 | } // end void setup() 30 | 31 | void loop() { 32 | 33 | // send temperature and humidity out over the UART 34 | // formatted with text that can be parsed on receiving side 35 | // format: "nnnHumidity" or "nnnTemperature" where nnn is a floating number 36 | Serial.print(SHT21.getHumidity()); 37 | Serial.println("Humidity"); 38 | delay(1000); 39 | 40 | Serial.print(SHT21.getTemperature()); 41 | Serial.println("Temperature"); 42 | delay(1000); 43 | 44 | } // end void loop() 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /ESP8266/SHT21_ESP8266_UART_Out/readme.md: -------------------------------------------------------------------------------- 1 | Demo showing how to read temperature and humidity out of the SHT21 digital sensor 2 | Sends the data out over the UART so it can be displayed on the serial monitor or 3 | interpreted by another hardware device for display on a screen etc. 4 | -------------------------------------------------------------------------------- /ESP8266/Simple_Web_Server/Basic_Web_Server_1.ino: -------------------------------------------------------------------------------- 1 | // ESP8266 Web Server Example 2 | // Target Hardware: esp8266 NodeMCU 3 | // 4 | // Creates a web server over wifi and allows controlling an led 5 | // 6 | // NodeMCU Pins 7 | // LED: D3 8 | // 9 | // Required libraries and board files: 10 | // esp8266 install from boards manager 11 | // 12 | // Gadget Reboot 13 | 14 | #include 15 | #include 16 | 17 | ESP8266WebServer server(80); // create webserver object to listen for HTTP requests on port 80 18 | 19 | const char* ssid = "ssid"; // wifi credentials 20 | const char* password = "password"; 21 | 22 | #define ledPin D3 23 | 24 | String htmlPage; // webpage text to be sent out by server when main page is accessed 25 | 26 | void setup() { 27 | Serial.begin(9600); 28 | 29 | digitalWrite(ledPin, LOW); // led is off initially 30 | pinMode(ledPin, OUTPUT); 31 | 32 | // Connect to WiFi network 33 | Serial.println(); 34 | Serial.println(); 35 | Serial.print("Connecting to WiFi..."); 36 | WiFi.mode(WIFI_STA); 37 | WiFi.disconnect(); // disconnect if previously connected 38 | delay(100); 39 | WiFi.begin(ssid, password); 40 | while (WiFi.status() != WL_CONNECTED) { 41 | delay(500); 42 | Serial.print("."); 43 | } 44 | Serial.println(); 45 | Serial.println("WiFi connected."); 46 | Serial.print("IP: "); 47 | Serial.println(WiFi.localIP()); 48 | 49 | // functions to call when client requests are received 50 | server.on("/", handleRoot); 51 | server.on("/LEDTOGGLE", handleLEDToggle); 52 | server.on("/LEDON", handleLEDOn); 53 | server.on("/LEDOFF", handleLEDOff); 54 | server.onNotFound(handleNotFound); 55 | 56 | server.begin(); // start web server 57 | Serial.println("HTTP server started"); 58 | } 59 | 60 | void loop(void) { 61 | server.handleClient(); // listen for HTTP requests from clients 62 | } 63 | 64 | 65 | // client request handling functions 66 | 67 | // send main web page when ip+"/" is accessed 68 | void handleRoot() { 69 | buildHtmlPage(); 70 | server.send(200, "text/html", htmlPage); 71 | } 72 | 73 | // toggle led and redirect to main page 74 | void handleLEDToggle() { 75 | digitalWrite(ledPin, !digitalRead(ledPin)); 76 | server.sendHeader("Location", "/"); 77 | server.send(303); 78 | } 79 | 80 | // turn led on and redirect to main page 81 | void handleLEDOn() { 82 | digitalWrite(ledPin, HIGH); 83 | server.sendHeader("Location", "/"); 84 | server.send(303); 85 | } 86 | 87 | // turn led off and redirect to main page 88 | void handleLEDOff() { 89 | digitalWrite(ledPin, LOW); 90 | server.sendHeader("Location", "/"); 91 | server.send(303); 92 | } 93 | 94 | // send HTTP status 404: Not Found when there's no handler for the client request 95 | void handleNotFound() { 96 | server.send(404, "text/plain", "404: Not found"); 97 | } 98 | 99 | // create the html page for the root path of the web server 100 | void buildHtmlPage() { 101 | htmlPage = ""; 102 | htmlPage += ""; 103 | htmlPage += ""; // header section 104 | htmlPage += "ESP8266 Web Server"; // title for browser window 105 | htmlPage += ""; 106 | 107 | htmlPage += ""; // body section, set background color 108 | 109 | // show led status and action buttons 110 | String ledState = ((digitalRead(ledPin)) ? "on" : "off"); 111 | htmlPage += "
LED: " + ledState; 112 | htmlPage += "
"; 113 | htmlPage += "
"; 114 | htmlPage += "
"; 115 | 116 | htmlPage += ""; 117 | htmlPage += ""; 118 | } 119 | -------------------------------------------------------------------------------- /ESP8266/Simple_Web_Server/Basic_Web_Server_2.ino: -------------------------------------------------------------------------------- 1 | // ESP8266 Web Server Example 2 | // Target Hardware: esp8266 NodeMCU 3 | // 4 | // Creates a web server over wifi and allows controlling an led and relay 5 | // while also displaying temperature and humidity data from an SHT-21 sensor. 6 | // 7 | // NodeMCU Pins 8 | // SCL: D1 9 | // SDA: D2 10 | // LED: D3 11 | // Relay: D5 12 | // 13 | // Required libraries and board files: 14 | // esp8266 install from boards manager 15 | // SHT21 https://github.com/markbeee/SHT21 16 | // 17 | // Gadget Reboot 18 | 19 | #include 20 | #include 21 | #include "SHT21.h" 22 | 23 | ESP8266WebServer server(80); // create webserver object to listen for HTTP requests on port 80 24 | SHT21 SHT21; // create i2c temperature/humidity sensor object 25 | 26 | const char* ssid = "ssid"; // wifi credentials 27 | const char* password = "password"; 28 | 29 | #define ledPin D3 30 | #define relayPin D5 31 | 32 | String htmlPage; // webpage text to be sent out by server when main page is accessed 33 | 34 | void setup() { 35 | Serial.begin(9600); 36 | 37 | SHT21.begin(); // init temp/humidity sensor 38 | 39 | digitalWrite(ledPin, LOW); // led is off initially 40 | pinMode(ledPin, OUTPUT); 41 | 42 | digitalWrite(relayPin, HIGH); // relay is not energized initially (active low) 43 | pinMode(relayPin, OUTPUT); 44 | 45 | // Connect to WiFi network 46 | Serial.println(); 47 | Serial.println(); 48 | Serial.print("Connecting to WiFi..."); 49 | WiFi.mode(WIFI_STA); 50 | WiFi.disconnect(); // disconnect if previously connected 51 | delay(100); 52 | WiFi.begin(ssid, password); 53 | while (WiFi.status() != WL_CONNECTED) { 54 | delay(500); 55 | Serial.print("."); 56 | } 57 | Serial.println(); 58 | Serial.println("WiFi connected."); 59 | Serial.print("IP: "); 60 | Serial.println(WiFi.localIP()); 61 | 62 | // functions to call when client requests are received 63 | server.on("/", handleRoot); 64 | server.on("/LEDTOGGLE", handleLEDToggle); 65 | server.on("/LEDON", handleLEDOn); 66 | server.on("/LEDOFF", handleLEDOff); 67 | server.on("/RELAYTOGGLE", handleRelayToggle); 68 | server.on("/RELAYON", handleRelayOn); 69 | server.on("/RELAYOFF", handleRelayOff); 70 | server.onNotFound(handleNotFound); 71 | 72 | server.begin(); // start web server 73 | Serial.println("HTTP server started"); 74 | } 75 | 76 | void loop(void) { 77 | server.handleClient(); // listen for HTTP requests from clients 78 | } 79 | 80 | 81 | // client request handling functions 82 | 83 | // send main web page when ip+"/" is accessed 84 | void handleRoot() { 85 | buildHtmlPage(); 86 | server.send(200, "text/html", htmlPage); 87 | } 88 | 89 | // toggle led and redirect to main page 90 | void handleLEDToggle() { 91 | digitalWrite(ledPin, !digitalRead(ledPin)); 92 | server.sendHeader("Location", "/"); 93 | server.send(303); 94 | } 95 | 96 | // turn led on and redirect to main page 97 | void handleLEDOn() { 98 | digitalWrite(ledPin, HIGH); 99 | server.sendHeader("Location", "/"); 100 | server.send(303); 101 | } 102 | 103 | // turn led off and redirect to main page 104 | void handleLEDOff() { 105 | digitalWrite(ledPin, LOW); 106 | server.sendHeader("Location", "/"); 107 | server.send(303); 108 | } 109 | 110 | // toggle relay and redirect to main page 111 | void handleRelayToggle() { 112 | digitalWrite(relayPin, !digitalRead(relayPin)); 113 | server.sendHeader("Location", "/"); 114 | server.send(303); 115 | } 116 | 117 | // turn relay on and redirect to main page 118 | void handleRelayOn() { 119 | digitalWrite(relayPin, LOW); 120 | server.sendHeader("Location", "/"); 121 | server.send(303); 122 | } 123 | 124 | // turn relay off and redirect to main page 125 | void handleRelayOff() { 126 | digitalWrite(relayPin, HIGH); 127 | server.sendHeader("Location", "/"); 128 | server.send(303); 129 | } 130 | 131 | // send HTTP status 404: Not Found when there's no handler for the client request 132 | void handleNotFound() { 133 | server.send(404, "text/plain", "404: Not found"); 134 | } 135 | 136 | // create the html page for the root path of the web server 137 | void buildHtmlPage() { 138 | htmlPage = ""; 139 | htmlPage += ""; 140 | htmlPage += ""; // header section 141 | htmlPage += "ESP8266 Web Server"; // title for browser window 142 | htmlPage += ""; // auto-refresh the page every 10 seconds to show new data 143 | htmlPage += ""; // UTF-8 allows the degree symbol to display correctly 144 | htmlPage += ""; 145 | 146 | htmlPage += ""; // body section, set background color 147 | 148 | // retrieve temperature/humidity from sensor to display on main page 149 | htmlPage += "
Temperature °C: " + String(SHT21.getTemperature()); 150 | htmlPage += "
Humidity %RH: " + String(SHT21.getHumidity()); 151 | htmlPage += "
"; 152 | 153 | // show led status and action buttons 154 | String ledState = ((digitalRead(ledPin)) ? "on" : "off"); 155 | htmlPage += "
LED: " + ledState; 156 | htmlPage += "
"; 157 | htmlPage += "
"; 158 | htmlPage += "
"; 159 | 160 | // show relay status and action buttons 161 | String relayState = ((!digitalRead(relayPin)) ? "on" : "off"); 162 | htmlPage += "
Relay: " + relayState; 163 | htmlPage += "
"; 164 | htmlPage += "
"; 165 | htmlPage += "
"; 166 | 167 | htmlPage += ""; 168 | htmlPage += ""; 169 | } 170 | -------------------------------------------------------------------------------- /ESP8266/Simple_Web_Server/WebServer_Schematic.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GadgetReboot/Arduino/adf95ad05b710d7a58421f86df913644a04948d4/ESP8266/Simple_Web_Server/WebServer_Schematic.jpg -------------------------------------------------------------------------------- /ESP8266/Simple_Web_Server/readme.md: -------------------------------------------------------------------------------- 1 | Example web servers with an ESP8266 to allow controlling devices from a browser 2 | and see data in the browser 3 | -------------------------------------------------------------------------------- /ESP8266/YoutubeSubCounter_7Seg_WEMOS/7Seg_Sub_Counter_Schematic.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GadgetReboot/Arduino/adf95ad05b710d7a58421f86df913644a04948d4/ESP8266/YoutubeSubCounter_7Seg_WEMOS/7Seg_Sub_Counter_Schematic.jpg -------------------------------------------------------------------------------- /ESP8266/YoutubeSubCounter_7Seg_WEMOS/readme.md: -------------------------------------------------------------------------------- 1 | A Youtube subscriber counter using WEMOS D1 Mini and a MAX7219 8 digit 7-segment display 2 | -------------------------------------------------------------------------------- /ESP8266/YoutubeSubscriberCounter/SubCounter_Schematic.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GadgetReboot/Arduino/adf95ad05b710d7a58421f86df913644a04948d4/ESP8266/YoutubeSubscriberCounter/SubCounter_Schematic.jpg -------------------------------------------------------------------------------- /ESP8266/YoutubeSubscriberCounter/YouTubeSubscriberCounter.ino: -------------------------------------------------------------------------------- 1 | // YouTube Channel Subscriber Counter 2 | // Target Hardware: esp8266 NodeMCU 3 | // 4 | // Uses the Youtube Data API to retrieve channel statistics 5 | // and display the subscriber count on an OLED and LCD display as well as serial monitor. 6 | // Can be adapted to display data on other displays. 7 | // 8 | // NodeMCU I2C Pins - defaults used by esp8266 board files in Arduino: 9 | // SCL: D1 10 | // SDA: D2 11 | // 12 | // Required libraries and board files: 13 | // esp8266 install from boards manager 14 | // YoutubeApi for accessing Youtube via API key 15 | // ArduinoJson required by YoutubeAPI 16 | // Adafruit_SSD1306 for OLED display 17 | // hd44780 for 16x2 LCD 18 | // 19 | // Gadget Reboot 20 | 21 | #include 22 | #include 23 | #include // I2C library 24 | #include // Youtube Data API to retrieve public channel stats 25 | #include // required by Youtube API 26 | #include // OLED library 27 | #include // LCD hd44780 library 28 | #include // I2C expander i/o class 29 | 30 | #define SCREEN_WIDTH 128 // OLED display width 31 | #define SCREEN_HEIGHT 64 // OLED display height 32 | #define OLED_RESET -1 // Not using this SPI signal so set to -1 33 | 34 | #define API_KEY "xxxxxxxxxxxxxxxxxxxx" // your google apps API key for Youtube Data API access 35 | #define CHANNEL_ID "yyyyyyyyyyyyyyyyyyyy" // your Youtube channel ID 36 | 37 | char ssid[] = "your network SSID name"; // your network SSID name 38 | char password[] = "your network password"; // your network password 39 | 40 | Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); // declare OLED object 41 | 42 | hd44780_I2Cexp lcd; // declare LCD object: auto locate & auto config expander chip 43 | 44 | // Instantiate the WiFiClientSecure object for use with Youtube API 45 | WiFiClientSecure client; 46 | YoutubeApi api(API_KEY, client); 47 | 48 | unsigned long api_mtbs = 60000; // time between api requests, in mS. 60,000 mS = 1 minute intervals 49 | unsigned long api_lasttime = 0; // last time api request occurred 50 | 51 | void setup() { 52 | 53 | Serial.begin(9600); 54 | 55 | // initialize OLED and print welcome msg 56 | display.begin(SSD1306_SWITCHCAPVCC, 0x3C); 57 | display.clearDisplay(); 58 | display.setTextSize(2); 59 | display.setTextColor(WHITE); 60 | display.println("Joining"); 61 | display.println("WiFi..."); 62 | display.display(); 63 | 64 | // initialize 16 char 2 line LCD and print welcome msg 65 | lcd.begin(16, 2); 66 | lcd.clear(); 67 | lcd.print("Joining WiFi..."); 68 | 69 | // set WiFi to station mode and disconnect from an AP if previously connected 70 | WiFi.mode(WIFI_STA); 71 | WiFi.disconnect(); 72 | delay(100); 73 | 74 | // attempt to connect to Wifi network 75 | Serial.print("Connecting Wifi: "); 76 | Serial.println(ssid); 77 | WiFi.begin(ssid, password); 78 | while (WiFi.status() != WL_CONNECTED) { 79 | Serial.print("."); 80 | delay(500); 81 | } 82 | 83 | // show WiFi status in serial monitor 84 | Serial.println(""); 85 | Serial.println("WiFi connected."); 86 | Serial.print("IP address: "); 87 | IPAddress ip = WiFi.localIP(); 88 | Serial.println(ip); 89 | 90 | // update WiFi info on OLED 91 | display.clearDisplay(); 92 | display.setTextSize(2); 93 | display.setTextColor(WHITE); 94 | display.setCursor(0, 0); 95 | display.println("WiFi IP: "); 96 | display.setTextSize(1); 97 | display.println(ip); 98 | display.display(); 99 | 100 | // update WiFi info on LCD 101 | lcd.clear(); 102 | lcd.print("WiFi IP:"); 103 | lcd.setCursor(0, 1); // lower left character position 104 | lcd.print(ip); 105 | 106 | // show WiFi info on screens for a few seconds before continuing 107 | delay(3000); 108 | 109 | // get channel info from Youtube API for initial display 110 | pollYoutubeAPI(); 111 | 112 | } // end setup() 113 | 114 | void loop() { 115 | 116 | // if it is time to poll the Youtube API, try to retrieve channel data 117 | if (millis() > api_lasttime + api_mtbs) 118 | pollYoutubeAPI(); 119 | 120 | } // end loop() 121 | 122 | // Other functions/routines 123 | 124 | void pollYoutubeAPI() { 125 | if (api.getChannelStatistics(CHANNEL_ID)) { 126 | 127 | Serial.println("---------Stats---------"); 128 | Serial.print("Subscriber Count: "); 129 | Serial.println(api.channelStats.subscriberCount); 130 | Serial.print("View Count: "); 131 | Serial.println(api.channelStats.viewCount); 132 | Serial.print("Comment Count: "); 133 | Serial.println(api.channelStats.commentCount); 134 | Serial.print("Video Count: "); 135 | Serial.println(api.channelStats.videoCount); 136 | // Probably not needed :) 137 | //Serial.print("hiddenSubscriberCount: "); 138 | //Serial.println(api.channelStats.hiddenSubscriberCount); 139 | Serial.println("-----------------------"); 140 | 141 | // show subscriber count on OLED 142 | display.clearDisplay(); 143 | display.setTextSize(2); 144 | display.setTextColor(WHITE); 145 | display.setCursor(0, 0); 146 | display.println("Gadget"); 147 | display.println("Reboot"); 148 | display.println("Subs: "); 149 | display.print(api.channelStats.subscriberCount); 150 | display.display(); 151 | 152 | // show subscriber count on LCD 153 | lcd.clear(); 154 | lcd.print("Gadget Reboot"); 155 | lcd.setCursor(0, 1); // lower left character position 156 | lcd.print("Subs:"); 157 | lcd.print(api.channelStats.subscriberCount); 158 | } 159 | 160 | api_lasttime = millis(); // start a new delay for next API poll interval 161 | 162 | } // end pollYoutubeAPI() 163 | 164 | 165 | -------------------------------------------------------------------------------- /ESP8266/YoutubeSubscriberCounter/readme.md: -------------------------------------------------------------------------------- 1 | Demo showing how to use ESP8266 on a NodeMCU module to access the Youtube Data API over WiFi, 2 | retrieve Youtube channel statistics and display the number of subscribers on a display. 3 | -------------------------------------------------------------------------------- /ESP8266/readme.md: -------------------------------------------------------------------------------- 1 | ESP8266 projects 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Arduino -------------------------------------------------------------------------------- /Teensy/AudioEffects/SDCardChorusTest/readme.md: -------------------------------------------------------------------------------- 1 | Apply a Chorus effect to a line in audio signal or wav file playing back from SD card 2 | -------------------------------------------------------------------------------- /Teensy/AudioEffects/SDCardFlangeTest/readme.md: -------------------------------------------------------------------------------- 1 | Apply a Flange effect to audio from line in or wav file playing from SD card. 2 | -------------------------------------------------------------------------------- /Teensy/AudioEffects/SDCardWavFilePlayerTest/SDCardWavFilePlayerTest.ino: -------------------------------------------------------------------------------- 1 | // Modified by Gadget Reboot for a series of demos/tests of audio 2 | // playback and processing. 3 | // 4 | // Tested using Teensyduino Version 1.46 and Arduino IDE Version 1.8.9 5 | // 6 | // Original sketch header comments from pjrc.com: 7 | // 8 | // Simple WAV file player example 9 | // 10 | // Three types of output may be used, by configuring the code below. 11 | // 12 | // 1: Digital I2S - Normally used with the audio shield: 13 | // http://www.pjrc.com/store/teensy3_audio.html 14 | // 15 | // 2: Digital S/PDIF - Connect pin 22 to a S/PDIF transmitter 16 | // https://www.oshpark.com/shared_projects/KcDBKHta 17 | // 18 | // 3: Analog DAC - Connect the DAC pin to an amplified speaker 19 | // http://www.pjrc.com/teensy/gui/?info=AudioOutputAnalog 20 | // 21 | // To configure the output type, first uncomment one of the three 22 | // output objects. If not using the audio shield, comment out 23 | // the audioShield lines in setup(), so it does not wait forever 24 | // trying to configure the SGTL5000 codec chip. 25 | // 26 | // The SD card may connect to different pins, depending on the 27 | // hardware you are using. Uncomment or configure the SD card 28 | // pins to match your hardware. 29 | // 30 | // This example code is in the public domain. 31 | 32 | #include 33 | #include 34 | #include 35 | #include 36 | #include 37 | #include 38 | 39 | // create audio component objects 40 | AudioPlaySdWav playWav1; // SD card wav file player 41 | AudioInputI2S audioInput; // audio shield input, mic or line-in selectable 42 | AudioMixer4 mixer1; // mixers to combine wav file and audio shield inputs 43 | AudioMixer4 mixer2; 44 | 45 | // Use one of these 3 output types: Digital I2S, Digital S/PDIF, or Analog DAC 46 | AudioOutputI2S audioOutput; 47 | //AudioOutputSPDIF audioOutput; 48 | //AudioOutputAnalog audioOutput; 49 | 50 | // wire up the interfaces between audio components with patch cords 51 | // mixer inputs 52 | AudioConnection patchCord1(playWav1, 0, mixer1, 0); // left channels into mixer 1 53 | AudioConnection patchCord2(audioInput, 0, mixer1, 1); 54 | 55 | AudioConnection patchCord3(playWav1, 1, mixer2, 0); // right channels into mixer 2 56 | AudioConnection patchCord4(audioInput, 1, mixer2, 1); 57 | 58 | // mixer outputs 59 | AudioConnection patchCord5(mixer1, 0, audioOutput, 0); 60 | AudioConnection patchCord6(mixer2, 0, audioOutput, 1); 61 | 62 | // object to allow control of the SGTL5000 audio shield settings 63 | AudioControlSGTL5000 audioShield; 64 | 65 | // buttons and potentiometers 66 | #define pot0 A13 67 | #define pot1 A12 68 | #define pot2 A14 69 | #define button0 30 70 | #define button1 29 71 | #define button2 28 72 | #define button3 27 73 | 74 | // attach button debouncers to input buttons 75 | Bounce db_button0 = Bounce(button0, 30); 76 | Bounce db_button1 = Bounce(button1, 30); 77 | Bounce db_button2 = Bounce(button2, 30); 78 | Bounce db_button3 = Bounce(button3, 30); 79 | 80 | // choose mic or line input for audio shield input path 81 | //const int inputChSelect = AUDIO_INPUT_MIC; 82 | const int inputChSelect = AUDIO_INPUT_LINEIN; 83 | 84 | // audio shield volume 85 | int masterVolume = 0; 86 | 87 | // uncomment one set of SD card SPI pins to use 88 | // Use these with the Teensy Audio Shield 89 | #define SDCARD_CS_PIN 10 90 | #define SDCARD_MOSI_PIN 7 91 | #define SDCARD_SCK_PIN 14 92 | 93 | // Use these with the Teensy 3.5 & 3.6 SD card 94 | //#define SDCARD_CS_PIN BUILTIN_SDCARD 95 | //#define SDCARD_MOSI_PIN 11 // not actually used 96 | //#define SDCARD_SCK_PIN 13 // not actually used 97 | 98 | // Use these for the SD+Wiz820 or other adaptors 99 | //#define SDCARD_CS_PIN 4 100 | //#define SDCARD_MOSI_PIN 11 101 | //#define SDCARD_SCK_PIN 13 102 | 103 | // wav filenames on SD card for playback 104 | char *wavFiles[] = {"01.WAV", "02.WAV", "03.WAV", "04.WAV", "05.WAV", "06.WAV", "07.WAV" 105 | }; 106 | byte wavNum = 0; // current wav file index playing from array list 107 | bool wavIsPlaying = false; // track if a wav file is currently playing or not 108 | 109 | void setup() { 110 | Serial.begin(9600); 111 | Serial.println("SD Player Demo\n"); 112 | 113 | // buttons are inputs with pullups 114 | pinMode(button0, INPUT_PULLUP); 115 | pinMode(button1, INPUT_PULLUP); 116 | pinMode(button2, INPUT_PULLUP); 117 | pinMode(button3, INPUT_PULLUP); 118 | 119 | // Audio connections require memory to work. For more 120 | // detailed information, see the MemoryAndCpuUsage example 121 | AudioMemory(8); 122 | 123 | // comment these out if not using the audio adaptor board. 124 | Serial.print("init audio shield..."); 125 | audioShield.enable(); 126 | audioShield.inputSelect(inputChSelect); // select mic or line-in for audio shield input source 127 | audioShield.volume(0.5); 128 | Serial.println("done."); 129 | 130 | mixer1.gain(0, 0.5); 131 | mixer1.gain(1, 0.5); 132 | mixer1.gain(2, 0); 133 | mixer1.gain(3, 0); 134 | 135 | mixer2.gain(0, 0.5); 136 | mixer2.gain(1, 0.5); 137 | mixer2.gain(2, 0); 138 | mixer2.gain(3, 0); 139 | 140 | Serial.print("init SD card..."); 141 | SPI.setMOSI(SDCARD_MOSI_PIN); 142 | SPI.setSCK(SDCARD_SCK_PIN); 143 | if (!(SD.begin(SDCARD_CS_PIN))) { 144 | // stop here, but print a message 145 | Serial.println("Unable to access the SD card. Program halted."); 146 | while (1); 147 | } 148 | Serial.println("done."); 149 | Serial.println("Waiting for control input..."); 150 | 151 | // reset audio resource usage stats. 152 | // useful if tracking max usage in main program 153 | AudioProcessorUsageMaxReset(); 154 | AudioMemoryUsageMaxReset(); 155 | } 156 | 157 | void playFile(const char *filename) 158 | { 159 | Serial.print("Start playing file: "); 160 | Serial.println(filename); 161 | 162 | // start playing the file. 163 | // sketch continues to run while the file plays. 164 | playWav1.play(filename); 165 | 166 | // A brief delay for the library to read WAV header info 167 | delay(5); 168 | } 169 | 170 | 171 | void loop() { 172 | 173 | // auto select next wav file if current file finishes playing 174 | // and if playback is enabled 175 | if ((!(playWav1.isPlaying())) && (wavIsPlaying)) { 176 | wavNum++; 177 | if (wavNum > 6) { 178 | wavNum = 0; 179 | } 180 | playFile(wavFiles[wavNum]); 181 | } 182 | 183 | // read volume control pot and set audio shield volume if required 184 | int vol = analogRead(pot0); 185 | if (vol != masterVolume) { 186 | masterVolume = vol; 187 | audioShield.volume((float)vol / 1023); // audio shield headphone out volume (optional) 188 | mixer1.gain(0, (float)vol / 1023); // software mixer input channel volume 189 | mixer1.gain(1, (float)vol / 1023); 190 | mixer2.gain(0, (float)vol / 1023); 191 | mixer2.gain(1, (float)vol / 1023); 192 | } 193 | 194 | // update the button debounce status so falling edges 195 | // can be detected and processed 196 | db_button0.update(); 197 | db_button1.update(); 198 | db_button2.update(); 199 | db_button3.update(); 200 | 201 | // button 0 pressed - toggle playback start/stop for current wav file 202 | if (db_button0.fallingEdge()) { 203 | if (playWav1.isPlaying()) { 204 | playWav1.stop(); 205 | wavIsPlaying = false; 206 | Serial.println("Playback stopped\n"); 207 | } 208 | else { 209 | playFile(wavFiles[wavNum]); 210 | wavIsPlaying = true; 211 | Serial.println("Playback started"); 212 | } 213 | //Serial.print("Audio memory usage max: "); 214 | //Serial.println(AudioMemoryUsageMax()); 215 | } 216 | 217 | // button 1 pressed - skip track forward 218 | if (db_button1.fallingEdge()) { 219 | Serial.println("Skip track forward"); 220 | if (wavNum == 6) 221 | wavNum = 0; 222 | else 223 | wavNum++; 224 | playFile(wavFiles[wavNum]); 225 | wavIsPlaying = true; 226 | } 227 | 228 | // button 2 pressed - skip track backward 229 | if (db_button2.fallingEdge()) { 230 | Serial.println("Skip track backward"); 231 | if (wavNum == 0) 232 | wavNum = 6; 233 | else 234 | wavNum--; 235 | playFile(wavFiles[wavNum]); 236 | wavIsPlaying = true; 237 | } 238 | 239 | } 240 | -------------------------------------------------------------------------------- /Teensy/AudioEffects/SDCardWavFilePlayerTest/readme.md: -------------------------------------------------------------------------------- 1 | Testing the ability to play back wav files from the SD card 2 | -------------------------------------------------------------------------------- /Teensy/AudioEffects/Teensy_AudioShield_Wiring.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GadgetReboot/Arduino/adf95ad05b710d7a58421f86df913644a04948d4/Teensy/AudioEffects/Teensy_AudioShield_Wiring.jpg -------------------------------------------------------------------------------- /Teensy/AudioEffects/Teensy_Audio_Schematic.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GadgetReboot/Arduino/adf95ad05b710d7a58421f86df913644a04948d4/Teensy/AudioEffects/Teensy_Audio_Schematic.jpg -------------------------------------------------------------------------------- /Teensy/AudioEffects/readme.md: -------------------------------------------------------------------------------- 1 | Testing some of the audio processing effects with Teensy 2 | eg. Chorus, Flange, Delay, Reverb etc 3 | -------------------------------------------------------------------------------- /Teensy/AudioTest/AudioSampleCashregister.h: -------------------------------------------------------------------------------- 1 | // Audio data converted from WAV file by wav2sketch 2 | 3 | extern const unsigned int AudioSampleCashregister[5809]; 4 | -------------------------------------------------------------------------------- /Teensy/AudioTest/AudioSampleGong.h: -------------------------------------------------------------------------------- 1 | // Audio data converted from WAV file by wav2sketch 2 | 3 | extern const unsigned int AudioSampleGong[27633]; 4 | -------------------------------------------------------------------------------- /Teensy/AudioTest/AudioSampleHihat.h: -------------------------------------------------------------------------------- 1 | // Audio data converted from WAV file by wav2sketch 2 | 3 | extern const unsigned int AudioSampleHihat[5953]; 4 | -------------------------------------------------------------------------------- /Teensy/AudioTest/AudioSampleKick.h: -------------------------------------------------------------------------------- 1 | // Audio data converted from WAV file by wav2sketch 2 | 3 | extern const unsigned int AudioSampleKick[2561]; 4 | -------------------------------------------------------------------------------- /Teensy/AudioTest/AudioSampleSnare.h: -------------------------------------------------------------------------------- 1 | // Audio data converted from WAV file by wav2sketch 2 | 3 | extern const unsigned int AudioSampleSnare[2817]; 4 | -------------------------------------------------------------------------------- /Teensy/AudioTest/AudioSampleTomtom.h: -------------------------------------------------------------------------------- 1 | // Audio data converted from WAV file by wav2sketch 2 | 3 | extern const unsigned int AudioSampleTomtom[3489]; 4 | -------------------------------------------------------------------------------- /Teensy/AudioTest/AudioTest.ino: -------------------------------------------------------------------------------- 1 | 2 | /* Teensy 3.6 Audio Library Demo 3 | * 4 | * Portions taken from the Teensy "Examples" and from 5 | * https://github.com/UECIDE/Teensy3/tree/master/cores/teensy3/files/libraries/Audio/examples/SamplePlayer 6 | * 7 | * Audio samples taken from various freesound.org sources under varying Creative Commons provisions 8 | * Attribution cited within sketch comments below. 9 | */ 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | // Button input pins on Teensy 3.6 18 | #define sound0Pin 32 19 | #define sound1Pin 31 20 | #define sound2Pin 30 21 | #define sound3Pin 29 22 | #define sound4Pin 28 23 | #define sound5Pin 27 24 | #define sound6Pin 26 25 | #define sound7Pin 25 26 | 27 | // WAV files converted to code by wav2sketch 28 | #include "AudioSampleSnare.h" // http://www.freesound.org/people/KEVOY/sounds/82583/ 29 | #include "AudioSampleTomtom.h" // http://www.freesound.org/people/zgump/sounds/86334/ 30 | #include "AudioSampleHihat.h" // http://www.freesound.org/people/mhc/sounds/102790/ 31 | #include "AudioSampleKick.h" // http://www.freesound.org/people/DWSD/sounds/171104/ 32 | #include "AudioSampleGong.h" // http://www.freesound.org/people/juskiddink/sounds/86773/ 33 | #include "AudioSampleCashregister.h" // http://www.freesound.org/people/kiddpark/sounds/201159/ 34 | 35 | // Create the Audio components. 36 | AudioPlayMemory sound0; 37 | AudioPlayMemory sound1; // six memory players 38 | AudioPlayMemory sound2; // for converted wav samples 39 | AudioPlayMemory sound3; 40 | AudioPlayMemory sound4; 41 | AudioPlayMemory sound5; 42 | AudioMixer4 mix1; // two 4-channel mixers are needed in 43 | AudioMixer4 mix2; // tandem to combine 6 audio sources 44 | AudioOutputI2S headphones; 45 | AudioOutputAnalog dac; // play to both I2S audio board and on-chip DAC 46 | 47 | // Internal synth generated sounds copied from Teensy example audio sketch 48 | AudioSynthSimpleDrum drum0; 49 | AudioSynthSimpleDrum drum1; 50 | AudioMixer4 mixer1; // 4 channel mixer to combine sounds and connect to other mixer input 51 | 52 | // Create Audio connections between the components 53 | AudioConnection c1(sound0, 0, mix1, 0); 54 | AudioConnection c2(sound1, 0, mix1, 1); 55 | AudioConnection c3(sound2, 0, mix1, 2); 56 | AudioConnection c4(sound3, 0, mix1, 3); 57 | AudioConnection c5(mix1, 0, mix2, 0); // output of mix1 into 1st input on mix2 58 | AudioConnection c6(sound4, 0, mix2, 1); 59 | AudioConnection c7(sound5, 0, mix2, 2); 60 | AudioConnection c8(mix2, 0, headphones, 0); 61 | AudioConnection c9(mix2, 0, headphones, 1); 62 | AudioConnection c10(mix2, 0, dac, 0); 63 | AudioConnection c11(mixer1, 0, mix2, 3); // tie in the internal synth mixer output to sample sounds mixer 64 | AudioConnection patchCord1(drum0, 0, mixer1, 0); 65 | AudioConnection patchCord2(drum1, 0, mixer1, 1); 66 | 67 | // Create an object to control the audio shield. 68 | AudioControlSGTL5000 audioShield; 69 | 70 | // Bounce objects to read six pushbuttons (pins 0-5) 71 | Bounce button0 = Bounce(sound0Pin, 5); 72 | Bounce button1 = Bounce(sound1Pin, 5); // 5 ms debounce time 73 | Bounce button2 = Bounce(sound2Pin, 5); 74 | Bounce button3 = Bounce(sound3Pin, 5); 75 | Bounce button4 = Bounce(sound4Pin, 5); 76 | Bounce button5 = Bounce(sound5Pin, 5); 77 | Bounce button6 = Bounce(sound6Pin, 5); 78 | Bounce button7 = Bounce(sound7Pin, 5); 79 | 80 | void setup() { 81 | // Configure the pushbutton pins for pullups. 82 | // Each button should connect from the pin to GND. 83 | pinMode(sound0Pin, INPUT_PULLUP); 84 | pinMode(sound1Pin, INPUT_PULLUP); 85 | pinMode(sound2Pin, INPUT_PULLUP); 86 | pinMode(sound3Pin, INPUT_PULLUP); 87 | pinMode(sound4Pin, INPUT_PULLUP); 88 | pinMode(sound5Pin, INPUT_PULLUP); 89 | pinMode(sound6Pin, INPUT_PULLUP); 90 | pinMode(sound7Pin, INPUT_PULLUP); 91 | 92 | // Audio connections require memory to work. For more 93 | // detailed information, see the MemoryAndCpuUsage example 94 | AudioMemory(25); 95 | 96 | // turn on the output 97 | audioShield.enable(); 98 | audioShield.volume(0.5); 99 | 100 | // by default the Teensy 3.1 DAC uses 3.3Vp-p output 101 | // if your 3.3V power has noise, switching to the 102 | // internal 1.2V reference can give you a clean signal 103 | //dac.analogReference(INTERNAL); 104 | 105 | // reduce the gain on mixer channels, so more than 1 106 | // sound can play simultaneously without clipping 107 | mix1.gain(0, 0.4); 108 | mix1.gain(1, 0.4); 109 | mix1.gain(2, 0.4); 110 | mix1.gain(3, 0.4); 111 | mix2.gain(1, 0.4); 112 | mix2.gain(2, 0.4); 113 | mixer1.gain(0, 0.4); 114 | mixer1.gain(1, 0.4); 115 | 116 | // configure what the synth drums will sound like 117 | drum0.frequency(60); 118 | drum0.length(300); 119 | drum0.secondMix(0.0); 120 | drum0.pitchMod(1.0); 121 | 122 | drum1.frequency(60); 123 | drum1.length(1500); 124 | drum1.secondMix(0.0); 125 | drum1.pitchMod(0.55); 126 | 127 | AudioInterrupts(); 128 | } 129 | 130 | void loop() { 131 | // Update all the button objects 132 | button0.update(); 133 | button1.update(); 134 | button2.update(); 135 | button3.update(); 136 | button4.update(); 137 | button5.update(); 138 | button6.update(); 139 | button7.update(); 140 | 141 | // When the buttons are pressed, just start a sound playing. 142 | // The audio library will play each sound through the mixers 143 | // so any combination can play simultaneously. 144 | // 145 | if (button0.fallingEdge()) { 146 | sound0.play(AudioSampleSnare); 147 | } 148 | if (button1.fallingEdge()) { 149 | sound1.play(AudioSampleTomtom); 150 | } 151 | if (button2.fallingEdge()) { 152 | sound2.play(AudioSampleHihat); 153 | } 154 | if (button3.fallingEdge()) { 155 | sound3.play(AudioSampleKick); 156 | } 157 | if (button4.fallingEdge()) { 158 | // comment this line to work with Teensy 3.0. 159 | // the Gong sound is very long, too much for 3.0's memory 160 | sound4.play(AudioSampleGong); 161 | } 162 | if (button5.fallingEdge()) { 163 | sound5.play(AudioSampleCashregister); 164 | } 165 | if (button6.fallingEdge()) { 166 | drum0.noteOn(); 167 | } 168 | if (button7.fallingEdge()) { 169 | drum1.noteOn(); 170 | } 171 | } 172 | 173 | -------------------------------------------------------------------------------- /Teensy/AudioTest/readme.md: -------------------------------------------------------------------------------- 1 | Testing the Teensy 3.6 with the audio board by playing back drum samples and generating internal synth drum sounds. 2 | -------------------------------------------------------------------------------- /Teensy/NES_To_USB/NES_To_USB.ino: -------------------------------------------------------------------------------- 1 | /* 2 | NES to USB Gamepad Controller 3 | Written for Teensy 3.6 4 | This code is in the public domain 5 | 6 | Controller Button States: 7 | nesRegister [7..0] = [Right, Left, Down, Up, Start, Select, B, A] 8 | 9 | NES controller pinout: 10 | _________ 11 | / | 12 | / O | Ground 13 | / | 14 | +VCC | O O | Clock 15 | | | 16 | N.C. | O O | Latch 17 | | | 18 | N.C. | O O | Data Out (To NES) 19 | |____________| 20 | 21 | */ 22 | 23 | 24 | // bit positions of each controller button in the status register 25 | const int A_BUTTON = 0; 26 | const int B_BUTTON = 1; 27 | const int SELECT_BUTTON = 2; 28 | const int START_BUTTON = 3; 29 | const int UP_BUTTON = 4; 30 | const int DOWN_BUTTON = 5; 31 | const int LEFT_BUTTON = 6; 32 | const int RIGHT_BUTTON = 7; 33 | 34 | const int shiftDelay = 20; // delay in microseconds to help with shift register setup/hold timing 35 | 36 | byte nesRegister = 255; // NES controller button states. 0=pressed 1=released 37 | 38 | // NES Pins 39 | int nesClock = 2; // NES controller 4021 clock pin 40 | int nesLatch = 3; // NES controller 4021 latch pin 41 | int nesData = 4; // NES controller 4021 data pin 42 | 43 | 44 | void setup() 45 | { 46 | // configure pins 47 | pinMode(nesData, INPUT); 48 | pinMode(nesClock, OUTPUT); 49 | pinMode(nesLatch, OUTPUT); 50 | 51 | digitalWrite(nesClock, LOW); // NES control lines idle low 52 | digitalWrite(nesLatch, LOW); 53 | 54 | Joystick.useManualSend(true); // analog joystick data will be sent manually 55 | } 56 | 57 | 58 | void loop() 59 | { 60 | // read the 8 controller buttons into the nesRegister 61 | // NES controller button states are asynchronously loaded into the 4021 while nesLatch is high 62 | // When nesLatch goes low, the first data bit is shifted to nesData 63 | // Button data is shifted to nesData on each low to high transition of nesClock 64 | 65 | digitalWrite(nesLatch, HIGH); // while the latch pin is high, buttons 66 | delayMicroseconds(shiftDelay); // impose a delay to allow a setup and hold time for any 4021 pins 67 | digitalWrite(nesLatch, LOW); 68 | 69 | for (int x = 0; x <= 7; x++) { // read in the 8 controller buttons that were latched into the 4021 70 | bitWrite(nesRegister, x, digitalRead(nesData)); // store the current button state on the data input into the correct nesRegister position 71 | digitalWrite(nesClock, HIGH); // generate a clock pulse to bring the next button to the data input 72 | delayMicroseconds(shiftDelay); 73 | digitalWrite(nesClock, LOW); 74 | } 75 | 76 | 77 | // assign the 8 NES controller button states to the USB joystick buttons. 78 | // the USB button state logic is inverted so 1=pressed 0=released 79 | Joystick.button(1, !bitRead(nesRegister, A_BUTTON)); 80 | Joystick.button(2, !bitRead(nesRegister, B_BUTTON)); 81 | Joystick.button(3, !bitRead(nesRegister, SELECT_BUTTON)); 82 | Joystick.button(4, !bitRead(nesRegister, START_BUTTON)); 83 | Joystick.button(5, !bitRead(nesRegister, UP_BUTTON)); 84 | Joystick.button(6, !bitRead(nesRegister, DOWN_BUTTON)); 85 | Joystick.button(7, !bitRead(nesRegister, LEFT_BUTTON)); 86 | Joystick.button(8, !bitRead(nesRegister, RIGHT_BUTTON)); 87 | 88 | //Joystick.X(analogRead(0)); //read analog joystick X and Y positions. Commented out for pure NES functionality 89 | //Joystick.Y(analogRead(1)); 90 | 91 | Joystick.send_now(); //send the current NES controller button states to the USB joystick 92 | 93 | } 94 | 95 | 96 | -------------------------------------------------------------------------------- /Teensy/NES_To_USB/readme.md: -------------------------------------------------------------------------------- 1 | Convert an NES controller to a USB joystick/gamepad 2 | -------------------------------------------------------------------------------- /Teensy/SNES_To_USB/SNES_To_USB.ino: -------------------------------------------------------------------------------- 1 | /* 2 | SNES to USB Gamepad Controller 3 | Written for Teensy 3.6 4 | This code is in the public domain 5 | 6 | Controller Button States: 7 | snesRegister [11..0] = [RT, LT, X, A, Right, Left, Down, Up, Start, Select, Y, B] 8 | 9 | SNES controller pinout: 10 | ________________ 11 | | 0 0 0 0 | 0 0 0 ) 12 | ---------------- 13 | + C L D N N G 14 | V L A A C C N 15 | K T T D 16 | C A 17 | H 18 | 19 | */ 20 | 21 | // bit positions of each controller button in the status register 22 | const int B_BUTTON = 0; 23 | const int Y_BUTTON = 1; 24 | const int SELECT_BUTTON = 2; 25 | const int START_BUTTON = 3; 26 | const int UP_BUTTON = 4; 27 | const int DOWN_BUTTON = 5; 28 | const int LEFT_BUTTON = 6; 29 | const int RIGHT_BUTTON = 7; 30 | const int A_BUTTON = 8; 31 | const int X_BUTTON = 9; 32 | const int LEFT_TRIGGER_BUTTON = 10; 33 | const int RIGHT_TRIGGER_BUTTON = 11; 34 | 35 | const int shiftDelay = 20; // delay in microseconds to help with shift register setup/hold timing 36 | 37 | int snesRegister; // SNES controller button states. 0=pressed 1=released 38 | 39 | // SNES Pins 40 | int snesClock = 2; // SNES controller clock pin 41 | int snesLatch = 3; // SNES controller latch pin 42 | int snesData = 4; // SNES controller data pin 43 | 44 | 45 | void setup() 46 | { 47 | // configure pins 48 | pinMode(snesData, INPUT); 49 | pinMode(snesClock, OUTPUT); 50 | pinMode(snesLatch, OUTPUT); 51 | 52 | digitalWrite(snesClock, LOW); // SNES control lines idle low 53 | digitalWrite(snesLatch, LOW); 54 | 55 | Joystick.useManualSend(true); // joystick data will be sent manually 56 | } 57 | 58 | 59 | void loop() 60 | { 61 | // read the 12 controller buttons into the snesRegister 62 | // SNES controller button states are asynchronously loaded into the shift register while snesLatch is high 63 | // When snesLatch goes low, the first data bit is shifted to snesData 64 | // Button data is shifted to snesData on each low to high transition of snesClock 65 | 66 | digitalWrite(snesLatch, HIGH); // while the latch pin is high, 67 | delayMicroseconds(shiftDelay); // impose a delay to allow a setup and hold time 68 | digitalWrite(snesLatch, LOW); 69 | 70 | for (int x = 0; x <= 11; x++) { // read in the 12 controller buttons that were latched 71 | bitWrite(snesRegister, x, digitalRead(snesData)); // store the current button state on the data input into the correct snesRegister position 72 | digitalWrite(snesClock, HIGH); // generate a clock pulse to bring the next button to the data input 73 | delayMicroseconds(shiftDelay); 74 | digitalWrite(snesClock, LOW); 75 | } 76 | 77 | 78 | // assign the 12 SNES controller button states to the USB joystick buttons. 79 | // the USB button state logic is inverted so 1=pressed 0=released 80 | Joystick.button(1, !bitRead(snesRegister, B_BUTTON)); 81 | Joystick.button(2, !bitRead(snesRegister, Y_BUTTON)); 82 | Joystick.button(3, !bitRead(snesRegister, SELECT_BUTTON)); 83 | Joystick.button(4, !bitRead(snesRegister, START_BUTTON)); 84 | Joystick.button(5, !bitRead(snesRegister, UP_BUTTON)); 85 | Joystick.button(6, !bitRead(snesRegister, DOWN_BUTTON)); 86 | Joystick.button(7, !bitRead(snesRegister, LEFT_BUTTON)); 87 | Joystick.button(8, !bitRead(snesRegister, RIGHT_BUTTON)); 88 | Joystick.button(9, !bitRead(snesRegister, A_BUTTON)); 89 | Joystick.button(10, !bitRead(snesRegister, X_BUTTON)); 90 | Joystick.button(11, !bitRead(snesRegister, LEFT_TRIGGER_BUTTON)); 91 | Joystick.button(12, !bitRead(snesRegister, RIGHT_TRIGGER_BUTTON)); 92 | 93 | Joystick.send_now(); //send the current SNES controller button states to the USB joystick 94 | 95 | } 96 | 97 | 98 | -------------------------------------------------------------------------------- /Teensy/SNES_To_USB/readme.md: -------------------------------------------------------------------------------- 1 | Using Teensy 3.6 to convert SNES controller to USB game pad 2 | -------------------------------------------------------------------------------- /Teensy/TeensyDemo/TeensyDemo.ino: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | This is an example for getting started using the Teensy 3.6 3 | in the Arduino development environment. 4 | 5 | This sketch uses code taken from an Arduino Uno sketch to control 6 | the 128x64 OLED display over I2C for seamless transfer to Teensy. 7 | 8 | PWM LED brightness control is implemented using PWM output, 9 | partially controlled by a potentiometer on an analog input to show 10 | some of the basic Arduino functionality being used on Teensy. 11 | 12 | This example requires the SSD1306 display driver by Adafruit: 13 | https://github.com/adafruit/Adafruit_SSD1306 14 | 15 | *********************************************************************/ 16 | 17 | #include 18 | #include 19 | 20 | #define OLED_RESET 4 21 | Adafruit_SSD1306 display(OLED_RESET); 22 | 23 | // make sure the SSD1306 driver is configured for 64 line height 24 | #if (SSD1306_LCDHEIGHT != 64) 25 | #error("Height incorrect, please fix Adafruit_SSD1306.h!"); 26 | #endif 27 | 28 | int redPin = 8; // RGB LED pins 29 | int greenPin = 9; 30 | int bluePin = 10; 31 | 32 | int potPin = 13; // potentiometer on analog 13 33 | int potLevel = 0; // analog reading stored for potentiometer 34 | 35 | byte ledIntensity = 0; // potentiometer reading is used to set LED brightness 36 | byte ledCounter = 0; // counter used to flash LED between two colors 37 | 38 | void setup() { 39 | 40 | Serial.begin(9600); 41 | 42 | // configure LED pins 43 | pinMode(redPin, OUTPUT); 44 | pinMode(greenPin, OUTPUT); 45 | pinMode(bluePin, OUTPUT); 46 | 47 | Serial.println("Begin Teensy Demo."); 48 | 49 | // initialize OLED display 50 | display.begin(SSD1306_SWITCHCAPVCC, 0x3C); 51 | display.setTextSize(2); 52 | display.setTextColor(WHITE); 53 | display.clearDisplay(); 54 | display.display(); 55 | } 56 | 57 | 58 | void loop() { 59 | 60 | potLevel = analogRead(potPin); // read potentiometer 61 | ledIntensity = (potLevel / 4); // scale pot reading down to a PWM 0-255 range 62 | 63 | // blue and red LED brightness are set by the pot, fading from opposite ends from full to dim 64 | analogWrite(bluePin, ledIntensity); // set blue LED brightness with PWM 65 | analogWrite(redPin, 255 - ledIntensity); // set red LED brightness with PWM 66 | 67 | Serial.println(); 68 | Serial.print("Pot: "); 69 | Serial.println(potLevel); 70 | Serial.print("Blue LED: "); 71 | Serial.println(ledIntensity); 72 | Serial.print("Red LED: "); 73 | Serial.println(255 - ledIntensity); 74 | 75 | display.clearDisplay(); 76 | display.setCursor(0, 0); 77 | display.print("Pot:"); 78 | display.println(potLevel); 79 | display.print("Blue: "); 80 | display.println(ledIntensity); 81 | display.print("Red: "); 82 | display.println(255 - ledIntensity); 83 | display.display(); 84 | 85 | // as the LED counter increments, it is used to flash green LED. 86 | ledCounter++; 87 | if (ledCounter == 32) { 88 | ledCounter = 0; 89 | } 90 | Serial.print("LED Counter: "); 91 | Serial.println(ledCounter); 92 | 93 | // set LED pins 94 | if (ledCounter > 15) { 95 | digitalWrite(greenPin, LOW); 96 | Serial.println("Green: On"); 97 | } 98 | else { 99 | digitalWrite(greenPin, HIGH); 100 | Serial.println("Green: Off"); 101 | } 102 | 103 | 104 | 105 | 106 | } 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | -------------------------------------------------------------------------------- /Teensy/TeensyDemo/TeensyDemo_Schematic.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GadgetReboot/Arduino/adf95ad05b710d7a58421f86df913644a04948d4/Teensy/TeensyDemo/TeensyDemo_Schematic.jpg -------------------------------------------------------------------------------- /Teensy/TeensyDemo/readme.md: -------------------------------------------------------------------------------- 1 | Getting started with Teensy 3.6 in the Arduino development environment. 2 | Using a 128x64 OLED, an RGB LED with PWM brightness, and a potentiometer 3 | on an analog input. 4 | -------------------------------------------------------------------------------- /Teensy/USB_HID_Mouse/USB_HID_MOUSE.ino: -------------------------------------------------------------------------------- 1 | 2 | /* 3 | Original code has been modified for Teensy 3.6 4 | 5 | Based on the JoystickMouseControl example code by Tom Igoe 6 | http://www.arduino.cc/en/Tutorial/JoystickMouseControl 7 | 8 | This example code is in the public domain. 9 | 10 | For Teensy, choose USB Type Mouse (or a type that includes Mouse) in the Tools menu. 11 | 12 | This sketch enables the Teensy to appear as a USB HID mouse controller, using a 2 axis 13 | analog joystick and buttons to control the mouse. 14 | 15 | Hardware: 16 | - 2-axis joystick connected to pins A0 and A1 17 | - pushbuttons connected to digital pins 0 and 1 18 | 19 | The mouse movement is always relative. This sketch reads two analog inputs 20 | that range from 0 to 1023 (or less on either end) and translates them into 21 | ranges of -6 to 6. 22 | The sketch assumes that the joystick resting values are around the middle of 23 | the range, but that they vary within a threshold. 24 | */ 25 | 26 | // set pin numbers for switch, joystick axes, and LED: 27 | const int mouseEnable = 1; // switch to turn on and off mouse control 28 | const int mouseLeftButton = 0; // input pin for the mouse pushButton 29 | const int xAxis = A0; // joystick X axis 30 | const int yAxis = A1; // joystick Y axis 31 | const int ledPin = 13; // Mouse control LED 32 | 33 | // parameters for reading the joystick: 34 | int range = 12; // output range of X or Y movement 35 | int responseDelay = 5; // response delay of the mouse, in ms 36 | int threshold = range / 4; // resting threshold 37 | int center = range / 2; // resting position value 38 | 39 | bool mouseIsActive = false; // whether or not to control the mouse 40 | int lastSwitchState = LOW; // previous switch state 41 | 42 | void setup() { 43 | pinMode(mouseEnable, INPUT_PULLUP); // the mouse enable toggle switch 44 | pinMode(mouseLeftButton, INPUT_PULLUP); // the left mouse button pin 45 | pinMode(ledPin, OUTPUT); // the LED pin 46 | Serial.begin(9600); 47 | Mouse.begin(); // take control of the mouse: 48 | Serial.println("USB HID Mouse Test."); // debug message to confirm sketch is running 49 | } 50 | 51 | void loop() { 52 | // read the mouse enable switch to control if mouse is active or disabled 53 | int switchState = digitalRead(mouseEnable); 54 | if (switchState != lastSwitchState) { 55 | if (switchState == HIGH) { 56 | mouseIsActive = !mouseIsActive; 57 | digitalWrite(ledPin, mouseIsActive); // turn on LED to indicate mouse state: 58 | } 59 | } 60 | // save switch state for next comparison: 61 | lastSwitchState = switchState; 62 | 63 | // read and scale the two axes: 64 | int xReading = readAxis(xAxis); 65 | int yReading = readAxis(yAxis); 66 | 67 | // if the mouse control state is active, move the mouse: 68 | if (mouseIsActive) { 69 | Mouse.move(xReading, yReading, 0); // not using scroll wheel, just move X and Y 70 | } 71 | 72 | // read the left mouse button and assert or release a click if necessary: 73 | if (digitalRead(mouseLeftButton) == LOW) { // low means button is currently pressed 74 | if (!Mouse.isPressed(MOUSE_LEFT)) { // so assert the left mouse button if not already done 75 | Mouse.press(MOUSE_LEFT); 76 | } 77 | } 78 | // else the mouse button is currently high/not pressed: 79 | else { 80 | if (Mouse.isPressed(MOUSE_LEFT)) { // if the left mouse button is currently pressed, release it: 81 | Mouse.release(MOUSE_LEFT); 82 | } 83 | } 84 | delay(responseDelay); 85 | } 86 | 87 | /* 88 | reads an axis (0 or 1 for x or y) and scales the analog input range to a range 89 | from 0 to 90 | 91 | Analog Reading: 0 -----------------------------
----------------------------- 1023 92 | Scaled Reading: 0 -----------------------------
----------------------------- 93 | 94 | */ 95 | 96 | int readAxis(int thisAxis) { 97 | // read the analog input: 98 | int reading = analogRead(thisAxis); 99 | 100 | // map the reading from the analog input range to the output range: 101 | reading = map(reading, 0, 1023, 0, range); 102 | 103 | // if the output reading is outside from the rest position threshold, use it: 104 | int distance = reading - center; 105 | 106 | if (abs(distance) < threshold) { 107 | distance = 0; 108 | } 109 | 110 | // return the distance for this axis: 111 | return distance; 112 | } 113 | 114 | 115 | -------------------------------------------------------------------------------- /Teensy/USB_HID_Mouse/readme.md: -------------------------------------------------------------------------------- 1 | Using the Teensy 3.6 as a USB Mouse 2 | Uses a two axis analog joystick for mouse cursor control 3 | Supports left click mouse button 4 | -------------------------------------------------------------------------------- /Teensy/readme.md: -------------------------------------------------------------------------------- 1 | Teensy Arduino Projects 2 | -------------------------------------------------------------------------------- /Uno/ACS712_AC_DC/ACS712_AC_DC_Current_Meas.ino: -------------------------------------------------------------------------------- 1 | // ACS712 AC/DC Current Sensor 2 | // 3 | // This version adapted from the libraries here: 4 | // https://github.com/rkoptev/ACS712-arduino 5 | // https://github.com/muratdemirtas/ACS712-arduino-1 6 | // 7 | // Added inputs to switch between AC or DC measurement mode 8 | // as well as to perform offset zero calibration when ready 9 | // (when there is no current flowing through the sensor) 10 | // 11 | // Gadget Reboot 12 | 13 | #include "ACS712.h" 14 | 15 | #define sensorInput A0 // sensor connects to analog 0 16 | #define dcMeasure 2 // measure DC/AC when input 2 is HIGH/LOW 17 | #define calInput 3 // offset calibration performed when input 3 = LOW 18 | 19 | // Sensor options: ACS712_05B = 5 amp, ACS712_20A = 20 amp, ACS712_30A = 30 amp 20 | ACS712 sensor(ACS712_05B, sensorInput); 21 | 22 | void setup() { 23 | Serial.begin(9600); 24 | 25 | pinMode (dcMeasure, INPUT_PULLUP); 26 | pinMode (calInput, INPUT_PULLUP); 27 | } 28 | 29 | void loop() { 30 | 31 | float currentReading; 32 | 33 | if (digitalRead(calInput) == LOW) { 34 | // calibrates the zero point of sensor. 35 | // only run when there is no current flow in order to detect the zero point. 36 | Serial.println("Calibrating... there must be no current flow through sensor during calibration."); 37 | sensor.calibrate(); 38 | Serial.println("Done!"); 39 | } 40 | 41 | if (digitalRead(dcMeasure)) 42 | currentReading = sensor.getCurrentDC(); // measure DC current 43 | else 44 | currentReading = sensor.getCurrentAC(60); // measure AC current at specified frequency (Hz) 45 | 46 | Serial.print("I = "); 47 | Serial.print(currentReading, 3); 48 | Serial.print(" A"); 49 | 50 | if (digitalRead(dcMeasure)) 51 | Serial.println(" DC"); 52 | else 53 | Serial.println(" AC"); 54 | 55 | delay(1000); 56 | } 57 | -------------------------------------------------------------------------------- /Uno/ACS712_AC_DC/readme.md: -------------------------------------------------------------------------------- 1 | Using the ACS712 current sensor for AC and DC current measurements on Arduino Uno. 2 | -------------------------------------------------------------------------------- /Uno/AVR_High_Voltage_Fuse_Programmer/12v switch.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GadgetReboot/Arduino/adf95ad05b710d7a58421f86df913644a04948d4/Uno/AVR_High_Voltage_Fuse_Programmer/12v switch.jpg -------------------------------------------------------------------------------- /Uno/AVR_High_Voltage_Fuse_Programmer/AVR_HV_Fuse_Programmer.ino: -------------------------------------------------------------------------------- 1 | // AVR High-voltage Serial Fuse Reprogrammer 2 | // 3 | // Gadget Reboot - modified fuse programming options in menu system 4 | // - changed 12 volt reset circuit and control logic 5 | // 6 | // This version adapted from the version by Ralph Bacon 7 | // https://github.com/RalphBacon/ATTiny85_Fuse_Resetter 8 | // Other History: 9 | // Adapted from code and design by Paul Willoughby 03/20/2010 10 | // http://www.rickety.us/2010/03/arduino-avr-high-voltage-serial-programmer/ 11 | // Inspired by Jeff Keyzer mightyohm.com 12 | // Serial Programming routines from ATtiny25/45/85 datasheet 13 | // 14 | // Fuse Calc: 15 | // http://www.engbedded.com/fusecalc/ 16 | 17 | 18 | #define SCI 12 // Target Clock Input 19 | #define SDO 11 // Target Data Output 20 | #define SII 10 // Target Instruction Input 21 | #define SDI 9 // Target Data Input 22 | #define VCC 8 // Target VCC 23 | #define RST 7 // Output to control 12V prog voltage to target Reset pin 24 | 25 | // required for accessing device fuse locations 26 | #define LFUSE 0x646C 27 | #define HFUSE 0x747C 28 | #define EFUSE 0x666E 29 | 30 | // Digispark default fuses 31 | #define LVAL1 0xE1 32 | #define HVAL1 0x5D 33 | #define EVAL1 0xFE 34 | 35 | // Digispark fuses with Reset pin enabled 36 | #define LVAL2 0xE1 37 | #define HVAL2 0xDD 38 | #define EVAL2 0xFE 39 | 40 | byte targetHVal = 0; 41 | byte targetLVal = 0; 42 | byte targetEVal = 0; 43 | bool readFuseOnly = true; // just reading, not writing 44 | 45 | // Define ATTiny series signatures 46 | #define ATTINY13 0x9007 // L: 0x6A, H: 0xFF 8 pin 47 | #define ATTINY24 0x910B // L: 0x62, H: 0xDF, E: 0xFF 14 pin 48 | #define ATTINY25 0x9108 // L: 0x62, H: 0xDF, E: 0xFF 8 pin 49 | #define ATTINY44 0x9207 // L: 0x62, H: 0xDF, E: 0xFFF 14 pin 50 | #define ATTINY45 0x9206 // L: 0x62, H: 0xDF, E: 0xFF 8 pin 51 | #define ATTINY84 0x930C // L: 0x62, H: 0xDF, E: 0xFFF 14 pin 52 | #define ATTINY85 0x930B // L: 0x62, H: 0xDF, E: 0xFF 8 pin 53 | 54 | void setup() { 55 | Serial.begin(9600); 56 | 57 | // configure programming pins 58 | digitalWrite(RST, LOW); // turn off 12V 59 | digitalWrite(VCC, LOW); 60 | digitalWrite(SDI, LOW); 61 | digitalWrite(SII, LOW); 62 | digitalWrite(SDO, LOW); 63 | pinMode(VCC, OUTPUT); 64 | pinMode(RST, OUTPUT); 65 | pinMode(SDI, OUTPUT); 66 | pinMode(SII, OUTPUT); 67 | pinMode(SCI, OUTPUT); 68 | pinMode(SDO, OUTPUT); // configured as input when in programming mode 69 | 70 | } 71 | 72 | void loop() { 73 | 74 | switch (getCommand()) { 75 | case 48: 76 | readFuseOnly = true; 77 | break; 78 | case 49: 79 | targetHVal = HVAL1; 80 | targetLVal = LVAL1; 81 | targetEVal = EVAL1; 82 | readFuseOnly = false; 83 | break; 84 | case 50: 85 | targetHVal = HVAL2; 86 | targetLVal = LVAL2; 87 | targetEVal = EVAL2; 88 | readFuseOnly = false; 89 | break; 90 | default: 91 | readFuseOnly = true; 92 | } 93 | 94 | /* 95 | From ATTiny85 Data Sheet 96 | ------------------------ 97 | 20.7.1 Enter High-voltage Serial Programming Mode 98 | 99 | The following algorithm puts the device in High-voltage Serial Programming mode: 100 | 1. Set Prog_enable pins listed in Table 20-14 to “000”, RESET pin and VCC to 0V. 101 | 2. Apply 4.5 - 5.5V between VCC and GND. Ensure that VCC reaches at least 1.8V within the next 20 µs. 102 | 3. Wait 20 - 60 µs, and apply 11.5 - 12.5V to RESET. 103 | 4. Keep the Prog_enable pins unchanged for at least 10 µs after the High-voltage has been applied to 104 | ensure the Prog_enable Signature has been latched. 105 | 5. Release the Prog_enable[2] pin to avoid drive contention on the Prog_enable[2]/SDO pin. 106 | 6. Wait at least 300 µs before giving any serial instructions on SDI/SII. 107 | 7. Exit Programming mode by power the device down or by bringing RESET pin to 0V. 108 | 109 | If the rise time of the VCC is unable to fulfill the requirements listed above, the following alternative algorithm can be 110 | used: 111 | 1. Set Prog_enable pins listed in Table 20-14 to “000”, RESET pin and VCC to 0V. 112 | 2. Apply 4.5 - 5.5V between VCC and GND. 113 | 3. Monitor VCC, and as soon as VCC reaches 0.9 - 1.1V, apply 11.5 - 12.5V to RESET. 114 | 4. Keep the Prog_enable pins unchanged for at least 10 µs after the High-voltage has been applied to 115 | ensure the Prog_enable Signature has been latched. 116 | 5. Release the Prog_enable[2] pin to avoid drive contention on the Prog_enable[2]/SDO pin. 117 | 6. Wait until VCC actually reaches 4.5 - 5.5V before giving any serial instructions on SDI/SII. 118 | 7. Exit Programming mode by power the device down or by bringing RESET pin to 0V 119 | */ 120 | 121 | // Future enhancement: monitor VCC with analog input and follow protocol more directly 122 | // for now, 100uS works to allow VCC to rise on Digispark board 123 | // powered by a high side P-ch FET switch 124 | 125 | // power up target device in high voltage programming mode 126 | pinMode(SDO, OUTPUT); // Set SDO to output 127 | digitalWrite(SDI, LOW); 128 | digitalWrite(SII, LOW); 129 | digitalWrite(SDO, LOW); 130 | digitalWrite(RST, LOW); // 12v Off 131 | digitalWrite(VCC, HIGH); // Vcc On 132 | delayMicroseconds(100); // Ensure VCC has reached at least 1.1v before applying 12v to reset 133 | digitalWrite(RST, HIGH); // 12v On 134 | delayMicroseconds(10); 135 | pinMode(SDO, INPUT); // Set SDO to input 136 | delayMicroseconds(300); // Ensure VCC has reached at least 4.5v before issuing instructions 137 | 138 | unsigned int sig = readSignature(); 139 | Serial.print("Signature: "); 140 | Serial.println(sig, HEX); 141 | Serial.println("Reading Fuses..."); 142 | readFuses(); 143 | 144 | if (!readFuseOnly) { 145 | Serial.println("Writing Fuses"); 146 | 147 | writeFuse(LFUSE, targetLVal); 148 | writeFuse(HFUSE, targetHVal); 149 | writeFuse(EFUSE, targetEVal); 150 | 151 | Serial.println("Reading Fuses..."); 152 | readFuses(); 153 | } 154 | 155 | digitalWrite(SCI, LOW); 156 | digitalWrite(RST, LOW); // 12v Off 157 | delayMicroseconds(40); 158 | digitalWrite(VCC, LOW); // Vcc Off 159 | 160 | } 161 | 162 | byte shiftOut (byte val1, byte val2) { 163 | int inBits = 0; 164 | //Wait until SDO goes high 165 | while (!digitalRead(SDO)) 166 | ; 167 | unsigned int dout = (unsigned int) val1 << 2; 168 | unsigned int iout = (unsigned int) val2 << 2; 169 | for (int ii = 10; ii >= 0; ii--) { 170 | digitalWrite(SDI, !!(dout & (1 << ii))); 171 | digitalWrite(SII, !!(iout & (1 << ii))); 172 | inBits <<= 1; inBits |= digitalRead(SDO); 173 | digitalWrite(SCI, HIGH); 174 | digitalWrite(SCI, LOW); 175 | } 176 | return inBits >> 2; 177 | } 178 | 179 | void writeFuse (unsigned int fuse, byte val) { 180 | shiftOut(0x40, 0x4C); 181 | shiftOut( val, 0x2C); 182 | shiftOut(0x00, (byte) (fuse >> 8)); 183 | shiftOut(0x00, (byte) fuse); 184 | } 185 | 186 | void readFuses () { 187 | byte val; 188 | 189 | shiftOut(0x04, 0x4C); // LFuse 190 | shiftOut(0x00, 0x68); 191 | val = shiftOut(0x00, 0x6C); 192 | Serial.print("LFuse:"); 193 | Serial.print(val, HEX); 194 | 195 | shiftOut(0x04, 0x4C); // HFuse 196 | shiftOut(0x00, 0x7A); 197 | val = shiftOut(0x00, 0x7E); 198 | Serial.print(", HFuse: "); 199 | Serial.print(val, HEX); 200 | 201 | shiftOut(0x04, 0x4C); // EFuse 202 | shiftOut(0x00, 0x6A); 203 | val = shiftOut(0x00, 0x6E); 204 | Serial.print(", EFuse: "); 205 | Serial.println(val, HEX); 206 | } 207 | 208 | unsigned int readSignature () { 209 | unsigned int sig = 0; 210 | byte val; 211 | for (int ii = 1; ii < 3; ii++) { 212 | shiftOut(0x08, 0x4C); 213 | shiftOut( ii, 0x0C); 214 | shiftOut(0x00, 0x68); 215 | val = shiftOut(0x00, 0x6C); 216 | sig = (sig << 8) + val; 217 | } 218 | return sig; 219 | } 220 | 221 | int getCommand() { 222 | 223 | // We must get a valid input to proceed 224 | int reply; 225 | 226 | do { 227 | Serial.println(); 228 | Serial.println("Enter 0 to read fuses (no writing)"); 229 | Serial.println("Enter 1 to use Digispark defaults"); 230 | Serial.println("Enter 2 to use P5 as Reset pin again"); 231 | Serial.println(); 232 | while (!Serial.available()) { 233 | // Wait for user input 234 | } 235 | reply = Serial.read(); 236 | } 237 | while (!(reply == 48 || reply == 49 || reply == 50)); 238 | 239 | return reply; 240 | } 241 | -------------------------------------------------------------------------------- /Uno/AVR_High_Voltage_Fuse_Programmer/Digispark HVSP Interface.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GadgetReboot/Arduino/adf95ad05b710d7a58421f86df913644a04948d4/Uno/AVR_High_Voltage_Fuse_Programmer/Digispark HVSP Interface.jpg -------------------------------------------------------------------------------- /Uno/AVR_High_Voltage_Fuse_Programmer/Fuse_HVP_Schematic.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GadgetReboot/Arduino/adf95ad05b710d7a58421f86df913644a04948d4/Uno/AVR_High_Voltage_Fuse_Programmer/Fuse_HVP_Schematic.jpg -------------------------------------------------------------------------------- /Uno/AVR_High_Voltage_Fuse_Programmer/VCC and 12v Reset Turn On Traces.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GadgetReboot/Arduino/adf95ad05b710d7a58421f86df913644a04948d4/Uno/AVR_High_Voltage_Fuse_Programmer/VCC and 12v Reset Turn On Traces.jpg -------------------------------------------------------------------------------- /Uno/AVR_High_Voltage_Fuse_Programmer/readme.md: -------------------------------------------------------------------------------- 1 | Using Arduino Uno as a High Voltage Fuse Programmer for Atmel ATTiny 2 | -------------------------------------------------------------------------------- /Uno/DHT22/DHT22_16x2_LCD/DHT22 16x2 LCD Schematic.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GadgetReboot/Arduino/adf95ad05b710d7a58421f86df913644a04948d4/Uno/DHT22/DHT22_16x2_LCD/DHT22 16x2 LCD Schematic.jpg -------------------------------------------------------------------------------- /Uno/DHT22/DHT22_16x2_LCD/DHT22_16x2_LCD.ino: -------------------------------------------------------------------------------- 1 | // Using the DHT2x Temperature/Humidity sensor with a 16x2 LCD via I2C 2 | // 3 | // Based on Adafruit sensor library example sketches 4 | // REQUIRES the following libraries: 5 | // - DHT Sensor Library: https://github.com/adafruit/DHT-sensor-library 6 | // - Adafruit Unified Sensor Lib: https://github.com/adafruit/Adafruit_Sensor 7 | // 8 | // Tested with Arduino IDE v1.8.9 9 | // Adafruit Unified Sensor v1.0.3 10 | // DHT Sensor Library v1.3.4 11 | // HD44780 v1.0.1 12 | // 13 | // Gadget Reboot 14 | 15 | #include "DHT.h" 16 | #include 17 | #include // LCD hd44780 library 18 | #include // i2c expander i/o class header 19 | 20 | #define DHTPIN 2 // digital pin connected to the DHT sensor 21 | #define DHTTYPE DHT22 // can be DHT11, DHT21, DHT22 22 | 23 | // create a DHT sensor object 24 | DHT dht(DHTPIN, DHTTYPE); 25 | 26 | // create lcd object: auto locate & auto config gpio expander chip 27 | hd44780_I2Cexp lcd; 28 | 29 | void setup(void) { 30 | 31 | Serial.begin(9600); 32 | Serial.println("DHT Temperature/Humidity Sensor"); 33 | Serial.println(); 34 | 35 | // initialize the DHT sensor 36 | dht.begin(); 37 | 38 | // initialize lcd 39 | lcd.begin(16, 2); 40 | lcd.clear(); 41 | } 42 | 43 | void loop() { 44 | 45 | // reading temperature or humidity takes about 250 milliseconds 46 | // read humidity 47 | float humidity = dht.readHumidity(); 48 | 49 | // read temperature: true=degF false=degC 50 | float tempC = dht.readTemperature(false); 51 | float tempF = dht.readTemperature(true); 52 | 53 | // Check if any reads failed 54 | if (isnan(humidity) || isnan(tempC) || isnan(tempF)) { 55 | Serial.println(F("Failed to read from DHT sensor!")); 56 | } 57 | else { 58 | Serial.print(F("Humidity: ")); 59 | Serial.print(humidity); 60 | Serial.print(F("% Temperature: ")); 61 | Serial.print(tempC); 62 | Serial.print(F("°C ")); 63 | Serial.print(tempF); 64 | Serial.print(F("°F ")); 65 | Serial.println(); 66 | 67 | lcd.setCursor(0, 0); 68 | lcd.print("T: "); 69 | lcd.print(tempC, 1); 70 | lcd.print((char)223); 71 | lcd.print("C "); 72 | lcd.print(tempF, 1); 73 | lcd.print((char)223); 74 | lcd.print("F"); 75 | 76 | lcd.setCursor(0, 1); 77 | lcd.print("Hum: "); 78 | lcd.print(humidity, 1); 79 | lcd.print("%RH"); 80 | } 81 | 82 | // DHT22 should only be read once every two seconds 83 | delay(2000); 84 | 85 | } // end void loop() 86 | -------------------------------------------------------------------------------- /Uno/DHT22/DHT22_16x2_LCD/readme.md: -------------------------------------------------------------------------------- 1 | DHT22 Temperature/Humidity sensor with a 16x2 I2C LCD 2 | -------------------------------------------------------------------------------- /Uno/DHT22/DHT22_Serial/DHT22_Serial.ino: -------------------------------------------------------------------------------- 1 | // Using the DHT2x Temperature/Humidity sensor with the serial monitor 2 | // 3 | // Based on Adafruit sensor library example sketches 4 | // REQUIRES the following libraries: 5 | // - DHT Sensor Library: https://github.com/adafruit/DHT-sensor-library 6 | // - Adafruit Unified Sensor Lib: https://github.com/adafruit/Adafruit_Sensor 7 | // 8 | // Tested with Arduino IDE v1.8.9 9 | // Adafruit Unified Sensor v1.0.3 10 | // DHT Sensor Library v1.3.4 11 | // 12 | // Gadget Reboot 13 | 14 | #include "DHT.h" 15 | 16 | #define DHTPIN 2 // Digital pin connected to the DHT sensor 17 | 18 | // Uncomment whatever type you're using! 19 | //#define DHTTYPE DHT11 // DHT 11 20 | #define DHTTYPE DHT22 // DHT 22 (AM2302), AM2321 21 | //#define DHTTYPE DHT21 // DHT 21 (AM2301) 22 | 23 | // create a DHT sensor object 24 | DHT dht(DHTPIN, DHTTYPE); 25 | 26 | void setup(void) { 27 | 28 | Serial.begin(9600); 29 | Serial.println("DHT Temperature/Humidity Sensor"); 30 | Serial.println(); 31 | 32 | // initialize the DHT sensor 33 | dht.begin(); 34 | } 35 | 36 | void loop() { 37 | 38 | // reading temperature or humidity takes about 250 milliseconds 39 | // read humidity 40 | float humidity = dht.readHumidity(); 41 | 42 | // read temperature: true=degF false=degC 43 | float tempC = dht.readTemperature(false); 44 | float tempF = dht.readTemperature(true); 45 | 46 | // Check if any reads failed 47 | if (isnan(humidity) || isnan(tempC) || isnan(tempF)) { 48 | Serial.println(F("Failed to read from DHT sensor!")); 49 | } 50 | else { 51 | Serial.print(F("Humidity: ")); 52 | Serial.print(humidity); 53 | Serial.print(F("% Temperature: ")); 54 | Serial.print(tempC); 55 | Serial.print(F("°C ")); 56 | Serial.print(tempF); 57 | Serial.print(F("°F ")); 58 | Serial.println(); 59 | } 60 | 61 | // DHT22 should only be read once every two seconds 62 | delay(2000); 63 | 64 | } // end void loop() 65 | -------------------------------------------------------------------------------- /Uno/DHT22/DHT22_Serial/DHT22_Serial_Schematic.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GadgetReboot/Arduino/adf95ad05b710d7a58421f86df913644a04948d4/Uno/DHT22/DHT22_Serial/DHT22_Serial_Schematic.jpg -------------------------------------------------------------------------------- /Uno/DHT22/DHT22_Serial/readme.md: -------------------------------------------------------------------------------- 1 | Using the DHT22 sensor with serial monitor output on Arduino Uno 2 | -------------------------------------------------------------------------------- /Uno/DHT22/TFT_480x320/DHT22 TFT LCD Schematic.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GadgetReboot/Arduino/adf95ad05b710d7a58421f86df913644a04948d4/Uno/DHT22/TFT_480x320/DHT22 TFT LCD Schematic.jpg -------------------------------------------------------------------------------- /Uno/DHT22/TFT_480x320/Display Images.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GadgetReboot/Arduino/adf95ad05b710d7a58421f86df913644a04948d4/Uno/DHT22/TFT_480x320/Display Images.jpg -------------------------------------------------------------------------------- /Uno/DHT22/TFT_480x320/readme.md: -------------------------------------------------------------------------------- 1 | DHT22 Temp/Humidity sensor with an MCUFriend 3.5" 480x320 touch screen 2 | -------------------------------------------------------------------------------- /Uno/DHT22/readme.md: -------------------------------------------------------------------------------- 1 | Projects using the DHT22 Temperature/Humidity sensor with Arduino Uno 2 | -------------------------------------------------------------------------------- /Uno/DMX512/DMXFade.ino: -------------------------------------------------------------------------------- 1 | /* 2 | Original sketch taken from https://github.com/PaulStoffregen/DmxSimple 3 | Modified by Gadget Reboot to use with a demo for two 4 | American DJ Micro Wash RGBW fixtures 5 | 6 | Welcome to DmxSimple. This library allows you to control DMX stage and 7 | ** architectural lighting and visual effects easily from Arduino. DmxSimple 8 | ** is compatible with the Tinker.it! DMX shield and all known DIY Arduino 9 | ** DMX control circuits. 10 | ** 11 | ** DmxSimple is available from: http://code.google.com/p/tinkerit/ 12 | ** Help and support: http://groups.google.com/group/dmxsimple */ 13 | 14 | #include 15 | 16 | void setup() { 17 | 18 | /* DMX devices typically need to receive a complete set of channels 19 | ** even if you only need to adjust the first channel. You can 20 | ** easily change the number of channels sent here. If you don't 21 | ** do this, DmxSimple will set the maximum channel number to the 22 | ** highest channel you DmxSimple.write() to. */ 23 | //DmxSimple.maxChannel(10); 24 | DmxSimple.usePin(3); 25 | DmxSimple.write(5, 255); // set master brightness to max 26 | DmxSimple.write(10, 255); // set master brightness to max 27 | } 28 | 29 | void loop() { 30 | int brightness; 31 | 32 | // RGBW Light Fixture 1 33 | 34 | for (brightness = 0; brightness <= 255; brightness++) { 35 | DmxSimple.write(1, brightness); 36 | delay(5); 37 | } 38 | for (brightness = 255; brightness >= 0; brightness--) { 39 | DmxSimple.write(1, brightness); 40 | delay(5); 41 | } 42 | 43 | for (brightness = 0; brightness <= 255; brightness++) { 44 | DmxSimple.write(2, brightness); 45 | delay(5); 46 | } 47 | for (brightness = 255; brightness >= 0; brightness--) { 48 | DmxSimple.write(2, brightness); 49 | delay(5); 50 | } 51 | 52 | for (brightness = 0; brightness <= 255; brightness++) { 53 | DmxSimple.write(3, brightness); 54 | delay(5); 55 | } 56 | for (brightness = 255; brightness >= 0; brightness--) { 57 | DmxSimple.write(3, brightness); 58 | delay(5); 59 | } 60 | 61 | for (brightness = 0; brightness <= 255; brightness++) { 62 | DmxSimple.write(4, brightness); 63 | delay(5); 64 | } 65 | for (brightness = 255; brightness >= 0; brightness--) { 66 | DmxSimple.write(4, brightness); 67 | delay(5); 68 | } 69 | 70 | 71 | // RGBW Light Fixture 2 72 | 73 | for (brightness = 0; brightness <= 255; brightness++) { 74 | DmxSimple.write(6, brightness); 75 | delay(5); 76 | } 77 | for (brightness = 255; brightness >= 0; brightness--) { 78 | DmxSimple.write(6, brightness); 79 | delay(5); 80 | } 81 | 82 | for (brightness = 0; brightness <= 255; brightness++) { 83 | DmxSimple.write(7, brightness); 84 | delay(5); 85 | } 86 | for (brightness = 255; brightness >= 0; brightness--) { 87 | DmxSimple.write(7, brightness); 88 | delay(5); 89 | } 90 | 91 | for (brightness = 0; brightness <= 255; brightness++) { 92 | DmxSimple.write(8, brightness); 93 | delay(5); 94 | } 95 | for (brightness = 255; brightness >= 0; brightness--) { 96 | DmxSimple.write(8, brightness); 97 | delay(5); 98 | } 99 | 100 | for (brightness = 0; brightness <= 255; brightness++) { 101 | DmxSimple.write(9, brightness); 102 | delay(5); 103 | } 104 | for (brightness = 255; brightness >= 0; brightness--) { 105 | DmxSimple.write(9, brightness); 106 | delay(5); 107 | } 108 | 109 | } 110 | -------------------------------------------------------------------------------- /Uno/DMX512/DMX_Manual_Control.ino: -------------------------------------------------------------------------------- 1 | /* 2 | Original sketch taken from https://github.com/PaulStoffregen/DmxSimple 3 | Modified by Gadget Reboot to use with a demo for two 4 | American DJ Micro Wash RGBW fixtures 5 | 6 | ** This program allows you to set DMX channels over the serial port. 7 | ** 8 | ** After uploading to Arduino, switch to Serial Monitor and set the baud rate 9 | ** to 9600. You can then set DMX channels using these commands: 10 | ** 11 | ** c : Select DMX channel 12 | ** v : Set DMX channel to new value 13 | ** 14 | ** These can be combined. For example: 15 | ** 100c355v : Set channel 100 to value 255. 16 | ** 17 | ** For more details, and compatible Processing sketch, 18 | ** visit http://code.google.com/p/tinkerit/wiki/SerialToDmx 19 | ** 20 | ** Help and support: http://groups.google.com/group/dmxsimple */ 21 | 22 | #include 23 | 24 | void setup() { 25 | Serial.begin(9600); 26 | 27 | /* DMX devices typically need to receive a complete set of channels 28 | ** even if you only need to adjust the first channel. You can 29 | ** easily change the number of channels sent here. If you don't 30 | ** do this, DmxSimple will set the maximum channel number to the 31 | ** highest channel you DmxSimple.write() to. */ 32 | //DmxSimple.maxChannel(10); 33 | DmxSimple.usePin(3); // digital output for DMX serial data 34 | DmxSimple.write(5, 255); // set fixture #1 master brightness to max 35 | DmxSimple.write(10, 255); // set fixture #2 master brightness to max 36 | 37 | Serial.println("DMX Manual Control"); 38 | Serial.println(); 39 | Serial.println("Syntax:"); 40 | Serial.println(" 123c : use DMX channel 123 (range: 1-512)"); 41 | Serial.println(" 45v : set current channel to value 45 (range: 0-255)"); 42 | } 43 | 44 | int value = 0; 45 | int channel; 46 | 47 | void loop() { 48 | int c; 49 | 50 | while (!Serial.available()); 51 | c = Serial.read(); 52 | if ((c >= '0') && (c <= '9')) { 53 | value = 10 * value + c - '0'; 54 | } else { 55 | if (c == 'c') channel = value; 56 | else if (c == 'v') { 57 | DmxSimple.write(channel, value); 58 | Serial.print("Ch:"); 59 | Serial.print(channel); 60 | Serial.print(" Value:"); 61 | Serial.print(value); 62 | Serial.println(); 63 | } 64 | value = 0; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /Uno/DMX512/DMX_Schematic.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GadgetReboot/Arduino/adf95ad05b710d7a58421f86df913644a04948d4/Uno/DMX512/DMX_Schematic.jpg -------------------------------------------------------------------------------- /Uno/DMX512/readme.md: -------------------------------------------------------------------------------- 1 | Examples showing how to use the DMXSimple library with Arduino 2 | to control DMX fixtures. 3 | 4 | Uses an Arduino digital output pin into an RS485 transceiver, which connects directly to a DMX device. 5 | -------------------------------------------------------------------------------- /Uno/DMX_Serial_Tx_Rx/DMX_Controller_Schematic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GadgetReboot/Arduino/adf95ad05b710d7a58421f86df913644a04948d4/Uno/DMX_Serial_Tx_Rx/DMX_Controller_Schematic.png -------------------------------------------------------------------------------- /Uno/DMX_Serial_Tx_Rx/DMX_Receiver_Schematic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GadgetReboot/Arduino/adf95ad05b710d7a58421f86df913644a04948d4/Uno/DMX_Serial_Tx_Rx/DMX_Receiver_Schematic.png -------------------------------------------------------------------------------- /Uno/DMX_Serial_Tx_Rx/Manual_Controller_Demo/DMX_Controller.ino: -------------------------------------------------------------------------------- 1 | // DMX Controller Example 2 | // Target Hardware: Arduino Uno 3 | // 4 | // Reads in two analog slider potentiometers and sends a value from 1 to 255 5 | // for each slider out to a DMX channel, selected by four push buttons. 6 | // 7 | // One push button toggles the target DMX main channel between two light fixtures 8 | // The first slider pot controls the master brightness on the selected light fixture 9 | // 10 | // Three push buttons select between red, green, and blue for slider pot #2 11 | // which will control the chosen color level for the current light fixture 12 | // 13 | // Required library: 14 | // DMXSerial install from library manager or https://github.com/mathertel/DMXSerial 15 | // Bounce2 install from library manager 16 | // 17 | // Gadget Reboot 18 | // https://www.youtube.com/gadgetreboot 19 | 20 | #include 21 | #include // button debounce library 22 | 23 | #define dmxModePin 2 // RS485 data direction control 24 | #define masterBrightnessPin A0 // slider pot #1 for current fixture master brightness 25 | #define channelLevelPin A1 // slider pot #2 for current fixture chosen color level 26 | #define redCtrlBtn 6 // button: slider pot #2 controls red 27 | #define grnCtrlBtn 5 // button: slider pot #2 controls green 28 | #define bluCtrlBtn 4 // button: slider pot #2 controls blue 29 | #define fixtureToggleBtn 3 // button: toggle current DMX fixture to control 30 | 31 | byte fixtureOneCh = 5; // first light fixture base channel 32 | byte fixtureTwoCh = 10; // second light fixture base channel 33 | byte masterBrightness; // master brightness level 34 | byte channelLevel; // channel level data 35 | byte targetFixture; // current fixture being controlled 36 | byte targetRGBChannel; // current RGB channel offset (from base ch) red=0 grn=1 blu=2 37 | byte brightnessChannel = 4; // brightness is channel 4 offset from the fixture base channel 38 | 39 | const int debounceInterval = 10; // debounce time (ms) for button readings 40 | Bounce buttonRedDB = Bounce(); // instantiate a bounce object for each button 41 | Bounce buttonGrnDB = Bounce(); 42 | Bounce buttonBluDB = Bounce(); 43 | Bounce buttonFixtureDB = Bounce(); 44 | 45 | void setup() { 46 | DMXSerial.init(DMXController, dmxModePin); // start the DMX master on the UART 47 | targetFixture = fixtureOneCh; // start out controlling the first light fixture 48 | targetRGBChannel = 0; // start out controlling the red level with slider pot #2 49 | 50 | pinMode(redCtrlBtn, INPUT_PULLUP); // configure push buttons 51 | pinMode(grnCtrlBtn, INPUT_PULLUP); 52 | pinMode(bluCtrlBtn, INPUT_PULLUP); 53 | pinMode(fixtureToggleBtn, INPUT_PULLUP); 54 | 55 | // attach buttons to debouncers 56 | buttonRedDB.attach(redCtrlBtn); 57 | buttonRedDB.interval(debounceInterval); 58 | 59 | buttonGrnDB.attach(grnCtrlBtn); 60 | buttonGrnDB.interval(debounceInterval); 61 | 62 | buttonBluDB.attach(bluCtrlBtn); 63 | buttonBluDB.interval(debounceInterval); 64 | 65 | buttonFixtureDB.attach(fixtureToggleBtn); 66 | buttonFixtureDB.interval(debounceInterval); 67 | 68 | // set default master brightness levels on both fixtures to 100 out of 255 69 | // the brightness channel is 4 channels above the base channel of each fixture 70 | // eg Fixture 1 is at base channel 5 so brightness is controlled by channel 9 71 | DMXSerial.write(fixtureOneCh + brightnessChannel, 100); 72 | DMXSerial.write(fixtureTwoCh + brightnessChannel, 100); 73 | } 74 | 75 | void loop() { 76 | 77 | // read slider pots and map a value from 1 to 255 to control 78 | // master brightness and color level, to be sent to the current 79 | // light fixture 80 | masterBrightness = map(analogRead(masterBrightnessPin), 0, 1023, 1, 255); 81 | channelLevel = map(analogRead(channelLevelPin), 0, 1023, 1, 255); 82 | 83 | // read the debounced push buttons and if one is pressed, assign 84 | // the current RGB color to control with slider pot #2, or assign 85 | // the current light fixture to control 86 | readButtons(); 87 | 88 | // send the DMX control data to the current light fixture to set the 89 | // individual RGB color levels and the master brightness 90 | DMXSerial.write(targetFixture + targetRGBChannel, channelLevel); 91 | DMXSerial.write(targetFixture + brightnessChannel, masterBrightness); 92 | } 93 | 94 | void readButtons() { 95 | 96 | // update the Bounce instances 97 | buttonRedDB.update(); 98 | buttonGrnDB.update(); 99 | buttonBluDB.update(); 100 | buttonFixtureDB.update(); 101 | 102 | if ( buttonRedDB.fell()) { 103 | targetRGBChannel = 0; 104 | } 105 | 106 | if ( buttonGrnDB.fell()) { 107 | targetRGBChannel = 1; 108 | } 109 | 110 | if ( buttonBluDB.fell()) { 111 | targetRGBChannel = 2; 112 | } 113 | 114 | if ( buttonFixtureDB.fell()) { 115 | if (targetFixture == fixtureOneCh) 116 | targetFixture = fixtureTwoCh; 117 | else if (targetFixture == fixtureTwoCh) 118 | targetFixture = fixtureOneCh; 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /Uno/DMX_Serial_Tx_Rx/Manual_Controller_Demo/DMX_Fixture_WS2812.ino: -------------------------------------------------------------------------------- 1 | // DMX Receiver/Fixture Example 2 | // Target Hardware: Arduino Uno 3 | // 4 | // Receives DMX data for red, green, and blue color levels as 5 | // well as a master brightness level, and controls an entire strip 6 | // of 60 WS2812B RGB LEDs as a single light fixture all with the 7 | // same color and brightness settings. 8 | // 9 | // Required library: 10 | // DMXSerial install from library manager or https://github.com/mathertel/DMXSerial 11 | // ws2812.h custom LED controller for better compatibility with DMX library 12 | // 13 | // Gadget Reboot 14 | // https://www.youtube.com/gadgetreboot 15 | 16 | #include 17 | #include "ws2812.h" // custom LED controller for compatibility 18 | #define dmxModePin 2 // configures RS485 for receive mode 19 | #define dmxBaseCh 10 // DMX channel 10 is the start channel. red = 10, grn = 11, blu = 12, bright = 14 20 | #define NUM_LEDS 60 // 60 LEDs numbered [0..59] 21 | 22 | 23 | byte maxBrightness = 75; // brightness range [off..on] = [0..255], keep dim for less current draw 24 | byte redLevel, // store the received channel level control data 25 | grnLevel, 26 | bluLevel, 27 | brightness; 28 | byte redCh = 0; // DMX channel offsets from base channel 29 | byte grnCh = 1; 30 | byte bluCh = 2; 31 | byte brightnessCh = 4; 32 | byte ledRgbData[NUM_LEDS * 3]; // array to store RGB data for all 60 LEDs (180 bytes total) 33 | 34 | void setup () { 35 | DMXSerial.init(DMXProbe, dmxModePin); // initialize DMX receiver in manual mode 36 | DMXSerial.maxChannel(dmxBaseCh + 4); // limit the number of DMX channels to read in 37 | 38 | setupNeopixel(); // configure LED strip for pin 12 (hard coded in ws2812.h) 39 | } 40 | 41 | 42 | void loop() { 43 | 44 | // when a DMX packet has arrived, read in the channel data 45 | // and set the color levels in the LED array 46 | if (DMXSerial.receive()) { 47 | redLevel = DMXSerial.read(dmxBaseCh + redCh); 48 | grnLevel = DMXSerial.read(dmxBaseCh + grnCh); 49 | bluLevel = DMXSerial.read(dmxBaseCh + bluCh); 50 | 51 | brightness = DMXSerial.read(dmxBaseCh + brightnessCh); 52 | brightness = map(brightness, 1, 255, 0, maxBrightness); 53 | 54 | // scale the RGB color levels based on the brightness level requested 55 | redLevel = float(redLevel) * (float(brightness) / float(maxBrightness)); 56 | grnLevel = float(grnLevel) * (float(brightness) / float(maxBrightness)); 57 | bluLevel = float(bluLevel) * (float(brightness) / float(maxBrightness)); 58 | 59 | // update all the red, green, and blue levels in the LED array 60 | // so that all reds are the same, all greens are the same, all blues are the same 61 | for (int i = 0; i < (NUM_LEDS * 3); i += 3) { 62 | ledRgbData[i] = redLevel; 63 | } 64 | 65 | for (int i = 1; i < (NUM_LEDS * 3); i += 3) { 66 | ledRgbData[i] = grnLevel; 67 | } 68 | 69 | for (int i = 2; i < (NUM_LEDS * 3); i += 3) { 70 | ledRgbData[i] = bluLevel; 71 | } 72 | } 73 | 74 | // update the led strip with the RGB data from the array 75 | updateNeopixel(ledRgbData, NUM_LEDS); 76 | } 77 | -------------------------------------------------------------------------------- /Uno/DMX_Serial_Tx_Rx/Manual_Controller_Demo/readme.md: -------------------------------------------------------------------------------- 1 | Using slider pots and push buttons, control the channel data for two light fixtures on the DMX bus 2 | -------------------------------------------------------------------------------- /Uno/DMX_Serial_Tx_Rx/Manual_Controller_Demo/ws2812.h: -------------------------------------------------------------------------------- 1 | // neopixel.h 2 | 3 | 4 | /* 5 | The Neopixel driving routines are taken from the article and sketch from bigjosh 6 | http://wp.josh.com/2014/05/13/ws2812-neopixels-are-not-so-finicky-once-you-get-to-know-them/ 7 | where the interrupt cli() and sei() are included in the sendBit function. 8 | At the sources from his github this is not the case but it's important for the usage with DMXSerial library. 9 | (see https://github.com/bigjosh/SimpleNeoPixelDemo ) 10 | 11 | These routines fit very good to the DMXSerial implementation because they switch on and off the 12 | Interrupt 13 | 14 | On DMX usual channels are used in the red then green then blue order. 15 | Neopixel wants colors in green then red then blue order so the 2 channels are switched. 16 | */ 17 | 18 | // ----- global defines from josh: ----- 19 | 20 | // These values are for the pin that connects to the Data Input pin on the LED strip. They correspond to... 21 | 22 | #define PIXEL_PORT PORTB // Port of the pin the pixels are connected to 23 | #define PIXEL_DDR DDRB // Port of the pin the pixels are connected to 24 | #define PIXEL_BIT 4 // Bit of the pin the pixels are connected to 25 | 26 | // This re3sults in the following Arduino Pins: 27 | // Arduino Yun: Digital Pin 8 28 | // DueMilinove/UNO: Digital Pin 12 29 | // Arduino Mega PWM Pin 4 30 | 31 | // You'll need to look up the port/bit combination for other boards. 32 | // Note that you could also include the DigitalWriteFast header file to not need to to this lookup. 33 | 34 | // These are the timing constraints taken mostly from the WS2812 datasheets 35 | // These are chosen to be conservative and avoid problems rather than for maximum throughput 36 | 37 | #define T1H 900 // Width of a 1 bit in ns 38 | #define T1L 600 // Width of a 1 bit in ns 39 | 40 | #define T0H 400 // Width of a 0 bit in ns 41 | #define T0L 900 // Width of a 0 bit in ns 42 | 43 | #define RES 6000 // Width of the low gap between bits to cause a frame to latch 44 | 45 | // Here are some convience defines for using nanoseconds specs to generate actual CPU delays 46 | 47 | #define NS_PER_SEC (1000000000L) // Note that this has to be SIGNED since we want to be able to check for negative values of derivatives 48 | 49 | #define CYCLES_PER_SEC (F_CPU) 50 | 51 | #define NS_PER_CYCLE ( NS_PER_SEC / CYCLES_PER_SEC ) 52 | 53 | #define NS_TO_CYCLES(n) ( (n) / NS_PER_CYCLE ) 54 | 55 | #define DELAY_CYCLES(n) ( ((n)>0) ? __builtin_avr_delay_cycles( n ) : __builtin_avr_delay_cycles( 0 ) ) // Make sure we never have a delay less than zero 56 | 57 | // Low level function with mixed in assembler code. 58 | 59 | // Actually send a bit to the string. We turn off optimizations to make sure the compile does 60 | // not reorder things and make it so the delay happens in the wrong place. 61 | inline void sendBit( bool bitVal ) 62 | { 63 | if (bitVal) { // 0 bit 64 | asm volatile ( 65 | "sbi %[port], %[bit] \n\t" // Set the output bit 66 | ".rept %[onCycles] \n\t" // Execute NOPs to delay exactly the specified number of cycles 67 | "nop \n\t" 68 | ".endr \n\t" 69 | "cbi %[port], %[bit] \n\t" // Clear the output bit 70 | ".rept %[offCycles] \n\t" // Execute NOPs to delay exactly the specified number of cycles 71 | "nop \n\t" 72 | ".endr \n\t" 73 | :: 74 | [port] "I" (_SFR_IO_ADDR(PIXEL_PORT)), 75 | [bit] "I" (PIXEL_BIT), 76 | [onCycles] "I" (NS_TO_CYCLES(T1H) - 2), // 1-bit width less overhead for the actual bit setting, note that this delay could be longer and everything would still work 77 | [offCycles] "I" (NS_TO_CYCLES(T1L) - 2) // Minimum interbit delay. Note that we probably don't need this at all since the loop overhead will be enough, but here for correctness 78 | ); 79 | 80 | } else { // 1 bit 81 | // ************************************************************************** 82 | // This line is really the only tight goldilocks timing in the whole program! 83 | // ************************************************************************** 84 | asm volatile ( 85 | "sbi %[port], %[bit] \n\t" // Set the output bit 86 | ".rept %[onCycles] \n\t" // Now timing actually matters. The 0-bit must be long enough to be detected but not too long or it will be a 1-bit 87 | "nop \n\t" // Execute NOPs to delay exactly the specified number of cycles 88 | ".endr \n\t" 89 | "cbi %[port], %[bit] \n\t" // Clear the output bit 90 | ".rept %[offCycles] \n\t" // Execute NOPs to delay exactly the specified number of cycles 91 | "nop \n\t" 92 | ".endr \n\t" 93 | :: 94 | [port] "I" (_SFR_IO_ADDR(PIXEL_PORT)), 95 | [bit] "I" (PIXEL_BIT), 96 | [onCycles] "I" (NS_TO_CYCLES(T0H) - 2), 97 | [offCycles] "I" (NS_TO_CYCLES(T0L) - 2) 98 | ); 99 | } // if 100 | 101 | // Note that the inter-bit gap can be as long as you want as long as it doesn't exceed the 5us reset timeout (which is A long time) 102 | // Here I have been generous and not tried to squeeze the gap tight but instead erred on the side of lots of extra time. 103 | // This has thenice side effect of avoid glitches on very long strings becuase 104 | } // sendBit() 105 | 106 | // Neopixel wants bit in highest-to-lowest order 107 | // so send highest bit (bit #7 in an 8-bit byte since they start at 0) 108 | inline void sendByte(uint8_t byte) 109 | { 110 | for (uint8_t bit = 0; bit < 8; bit++) { 111 | sendBit(byte & 0x80); 112 | byte <<= 113 | 1; // and then shift left so bit 6 moves into 7, 5 moves into 6, etc 114 | } // for 115 | } // sendByte() 116 | 117 | /* 118 | The following three functions are the public API: 119 | ledSetup() - set up the pin that is connected to the string. Call once at the begining of the program. 120 | sendPixel( r g , b ) - send a single pixel to the string. Call this once for each pixel in a frame. 121 | show() - show the recently sent pixel on the LEDs . Call once per frame. 122 | */ 123 | 124 | // Set the specified pin up as digital out 125 | 126 | void sendPixel(uint8_t r, uint8_t g, uint8_t b) { 127 | sendByte(g); // Neopixel wants colors in green then red then blue order 128 | sendByte(r); 129 | sendByte(b); 130 | } // sendPixel 131 | 132 | 133 | // ----- defines and routines from josh - End ----- 134 | 135 | void setupNeopixel() { 136 | bitSet( PIXEL_DDR , PIXEL_BIT ); 137 | } // setupNeopixel() 138 | 139 | 140 | // read data from the DMX buffer (RGB) and send it to the neopixels... 141 | void updateNeopixel(uint8_t *ptr, uint8_t pixels) { 142 | uint8_t r, g, b; 143 | 144 | // no interrupt is welcome. 145 | cli(); 146 | 147 | for (int p = 0; p < pixels; p++ ) { 148 | r = *ptr++; 149 | g = *ptr++; 150 | b = *ptr++; 151 | // send to Neopixels 152 | // sendPixel(r, g , b); 153 | sendPixel(r >> 2, g >> 2, b >> 2); 154 | } // for 155 | 156 | // interrupt may come. 157 | sei(); 158 | 159 | // Just wait long enough without sending any bots to cause the pixels to latch and display the last sent frame 160 | _delay_us((RES / 1000UL) + 1); 161 | } // updateNeopixel() 162 | 163 | // End -------------------------------------------------------------------------------- /Uno/DMX_Serial_Tx_Rx/WS2812B_60_Test/DMX_WS2812_Controller_Demo.ino: -------------------------------------------------------------------------------- 1 | // DMX Controller Example for WS2812B RGB LEDs 2 | // Target Hardware: Arduino Uno 3 | // 4 | // Sends individual RGB levels for 60 WS2812B LEDs (60*3 = 180 DMX channels total) 5 | // over an RS485 link in DMX packet format, to be decoded and sent out to a 60 LED strip. 6 | // The test pattern is an LED chaser where two different color bars run end to end 7 | // along the strip at different speeds, crossing over each other when they meet. 8 | // 9 | // The first DMX channel is 1 so the 60 LED RGB values are sent sequentially in 10 | // channels 1 to 180, eg: 11 | // Ch 1: LED 0 RED value [0-255] 12 | // Ch 2: LED 0 GREEN value [0-255] 13 | // Ch 3: LED 0 BLUE value [0-255] 14 | // Ch 178: LED 59 RED value [0-255] 15 | // Ch 179: LED 59 GREEN value [0-255] 16 | // Ch 180: LED 59 BLUE value [0-255] 17 | // 18 | // Required library: 19 | // DMXSerial install from library manager or https://github.com/mathertel/DMXSerial 20 | // 21 | // Gadget Reboot 22 | // https://www.youtube.com/gadgetreboot 23 | 24 | 25 | #include 26 | 27 | #define dmxModePin 2 // RS485 data direction control pin 28 | #define NUM_LEDS 60 // there will be RGB data for 60 LEDs 29 | 30 | byte rgbData[NUM_LEDS * 3]; // array to hold RGB data for 60 LEDs 31 | 32 | int onePos = 7; // position and direction markers for two LED chaser bars 33 | int twoPos = 8; 34 | byte oneDir = 0; 35 | byte twoDir = 0; 36 | 37 | void setup() { 38 | DMXSerial.init(DMXController, dmxModePin); // initialize a DMX controller on the UART 39 | } 40 | 41 | void loop() { 42 | 43 | // draw the green and blue LED bars at their current 44 | // position along the LED strip by setting the relevant 45 | // color brightness levels in the LED RGB data array. 46 | // each bar is 3 LEDs long so set the color of an LED followed by 47 | // the led directly before and after it 48 | rgbData[onePos] = 150; 49 | rgbData[max(onePos - 3, 0)] = 150; 50 | rgbData[min(onePos + 3, (NUM_LEDS * 3) - 3)] = 150; 51 | 52 | rgbData[twoPos] = 150; 53 | rgbData[max(twoPos - 3, 0)] = 150; 54 | rgbData[min(twoPos + 3, (NUM_LEDS * 3) - 3)] = 150; 55 | 56 | // with the color bars configured in the LED RGB array, 57 | // send the entire array out as a DMX packet containing 58 | // 180 channels of RGB data for 60 LEDs (RGB x 60 = 180 ch) 59 | // delay a short while to create animated effect before updating 60 | // and re-drawing the next LED bars 61 | sendDmxData(); 62 | delay(100); 63 | 64 | // turn recently drawn LEDs off (brightness = 0) so they can be 65 | // re-drawn on the next loop in the next calculated position. 66 | rgbData[onePos] = 0; 67 | rgbData[max(onePos - 3, 0)] = 0; 68 | rgbData[min(onePos + 3, (NUM_LEDS * 3) - 3)] = 0; 69 | 70 | rgbData[twoPos] = 0; 71 | rgbData[max(twoPos - 3, 0)] = 0; 72 | rgbData[min(twoPos + 3, (NUM_LEDS * 3) - 3)] = 0; 73 | 74 | // transmit the revised LED data 75 | sendDmxData(); 76 | 77 | // calculate the next position of each LED line by advancing the 78 | // LED position in the forward or reverse direction as required. 79 | // if the line reaches the end of the LED strip, it is time to 80 | // change its direction. 81 | if (oneDir == 0) { // if going forward 82 | onePos += 12; 83 | if (onePos >= (NUM_LEDS * 3)) { 84 | onePos = (NUM_LEDS * 3) - 5; 85 | oneDir = 1; // go in reverse direction 86 | } 87 | } 88 | 89 | if (oneDir == 1) { // if going reverse 90 | onePos -= 12; 91 | if (onePos <= 0) { 92 | onePos = 4; 93 | oneDir = 0; // go in forward direction 94 | } 95 | } 96 | 97 | if (twoDir == 0) { // if going forward 98 | twoPos += 9; 99 | if (twoPos >= (NUM_LEDS * 3)) { 100 | twoPos = (NUM_LEDS * 3) - 7; 101 | twoDir = 1; // go in reverse direction 102 | } 103 | } 104 | 105 | if (twoDir == 1) { // if going reverse 106 | twoPos -= 9; 107 | if (twoPos <= 0) { 108 | twoPos = 5; 109 | twoDir = 0; // go in forward direction 110 | } 111 | } 112 | 113 | } 114 | 115 | // send the RGB LED data for 60 LEDs 116 | // DMX channel 1 through 180 = LED array [0..179] 117 | void sendDmxData() { 118 | for (int i = 1; i < (1 + (NUM_LEDS * 3)); i++) { 119 | DMXSerial.write(i, rgbData[i - 1]); 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /Uno/DMX_Serial_Tx_Rx/WS2812B_60_Test/DMX_WS2812_Fixture_Demo.ino: -------------------------------------------------------------------------------- 1 | // DMX Receiver/Fixture Example for WS2812B RGB LEDs 2 | // Target Hardware: Arduino Uno 3 | // 4 | // Receives individual RGB levels for 60 WS2812B LEDs (60*3 = 180 DMX channels total) 5 | // over an RS485 link in DMX packet format, to be decoded and sent out to a 60 LED strip. 6 | // The test pattern is an LED chaser where two different color bars run end to end 7 | // along the strip at different speeds, crossing over each other when they meet. 8 | // 9 | // The first DMX channel is 1 so the 60 LED RGB values are sent sequentially in 10 | // channels 1 to 180, eg: 11 | // Ch 1: LED 0 RED value [0-255] 12 | // Ch 2: LED 0 GREEN value [0-255] 13 | // Ch 3: LED 0 BLUE value [0-255] 14 | // Ch 178: LED 59 RED value [0-255] 15 | // Ch 179: LED 59 GREEN value [0-255] 16 | // Ch 180: LED 59 BLUE value [0-255] 17 | // 18 | // Required library: 19 | // DMXSerial install from library manager or https://github.com/mathertel/DMXSerial 20 | // 21 | // Gadget Reboot 22 | // https://www.youtube.com/gadgetreboot 23 | 24 | #include 25 | #include "ws2812.h" // a specific LED controller that disables interrupts to work better 26 | 27 | #define NUM_LEDS 60 // number of RGB LEDs on strip 28 | #define DMXSTART 1 // first DMX channel 29 | #define DMXLENGTH (NUM_LEDS*3) // number of DMX channels used (3*60 LEDs) 30 | 31 | void setup () { 32 | 33 | DMXSerial.init(DMXProbe); // initialize DMX bus in manual access mode 34 | DMXSerial.maxChannel(DMXLENGTH); // "onUpdate" will be called when all new ch data has arrived 35 | 36 | setupNeopixel(); // setup the LED output hardcoded to pin 12 in ws2812.h 37 | 38 | } 39 | 40 | 41 | void loop() { 42 | // wait for an incomming DMX packet and write 43 | // the RGB data for 60 LEDs on the strip 44 | if (DMXSerial.receive()) { 45 | updateNeopixel(DMXSerial.getBuffer() + DMXSTART, NUM_LEDS); 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /Uno/DMX_Serial_Tx_Rx/WS2812B_60_Test/readme.md: -------------------------------------------------------------------------------- 1 | Send RGB data for 60 WS2812B LEDs over DMX using 180 channels (3x60) 2 | -------------------------------------------------------------------------------- /Uno/DMX_Serial_Tx_Rx/WS2812B_60_Test/ws2812.h: -------------------------------------------------------------------------------- 1 | // neopixel.h 2 | 3 | 4 | /* 5 | The Neopixel driving routines are taken from the article and sketch from bigjosh 6 | http://wp.josh.com/2014/05/13/ws2812-neopixels-are-not-so-finicky-once-you-get-to-know-them/ 7 | where the interrupt cli() and sei() are included in the sendBit function. 8 | At the sources from his github this is not the case but it's important for the usage with DMXSerial library. 9 | (see https://github.com/bigjosh/SimpleNeoPixelDemo ) 10 | 11 | These routines fit very good to the DMXSerial implementation because they switch on and off the 12 | Interrupt 13 | 14 | On DMX usual channels are used in the red then green then blue order. 15 | Neopixel wants colors in green then red then blue order so the 2 channels are switched. 16 | */ 17 | 18 | // ----- global defines from josh: ----- 19 | 20 | // These values are for the pin that connects to the Data Input pin on the LED strip. They correspond to... 21 | 22 | #define PIXEL_PORT PORTB // Port of the pin the pixels are connected to 23 | #define PIXEL_DDR DDRB // Port of the pin the pixels are connected to 24 | #define PIXEL_BIT 4 // Bit of the pin the pixels are connected to 25 | 26 | // This re3sults in the following Arduino Pins: 27 | // Arduino Yun: Digital Pin 8 28 | // DueMilinove/UNO: Digital Pin 12 29 | // Arduino Mega PWM Pin 4 30 | 31 | // You'll need to look up the port/bit combination for other boards. 32 | // Note that you could also include the DigitalWriteFast header file to not need to to this lookup. 33 | 34 | // These are the timing constraints taken mostly from the WS2812 datasheets 35 | // These are chosen to be conservative and avoid problems rather than for maximum throughput 36 | 37 | #define T1H 900 // Width of a 1 bit in ns 38 | #define T1L 600 // Width of a 1 bit in ns 39 | 40 | #define T0H 400 // Width of a 0 bit in ns 41 | #define T0L 900 // Width of a 0 bit in ns 42 | 43 | #define RES 6000 // Width of the low gap between bits to cause a frame to latch 44 | 45 | // Here are some convience defines for using nanoseconds specs to generate actual CPU delays 46 | 47 | #define NS_PER_SEC (1000000000L) // Note that this has to be SIGNED since we want to be able to check for negative values of derivatives 48 | 49 | #define CYCLES_PER_SEC (F_CPU) 50 | 51 | #define NS_PER_CYCLE ( NS_PER_SEC / CYCLES_PER_SEC ) 52 | 53 | #define NS_TO_CYCLES(n) ( (n) / NS_PER_CYCLE ) 54 | 55 | #define DELAY_CYCLES(n) ( ((n)>0) ? __builtin_avr_delay_cycles( n ) : __builtin_avr_delay_cycles( 0 ) ) // Make sure we never have a delay less than zero 56 | 57 | // Low level function with mixed in assembler code. 58 | 59 | // Actually send a bit to the string. We turn off optimizations to make sure the compile does 60 | // not reorder things and make it so the delay happens in the wrong place. 61 | inline void sendBit( bool bitVal ) 62 | { 63 | if (bitVal) { // 0 bit 64 | asm volatile ( 65 | "sbi %[port], %[bit] \n\t" // Set the output bit 66 | ".rept %[onCycles] \n\t" // Execute NOPs to delay exactly the specified number of cycles 67 | "nop \n\t" 68 | ".endr \n\t" 69 | "cbi %[port], %[bit] \n\t" // Clear the output bit 70 | ".rept %[offCycles] \n\t" // Execute NOPs to delay exactly the specified number of cycles 71 | "nop \n\t" 72 | ".endr \n\t" 73 | :: 74 | [port] "I" (_SFR_IO_ADDR(PIXEL_PORT)), 75 | [bit] "I" (PIXEL_BIT), 76 | [onCycles] "I" (NS_TO_CYCLES(T1H) - 2), // 1-bit width less overhead for the actual bit setting, note that this delay could be longer and everything would still work 77 | [offCycles] "I" (NS_TO_CYCLES(T1L) - 2) // Minimum interbit delay. Note that we probably don't need this at all since the loop overhead will be enough, but here for correctness 78 | ); 79 | 80 | } else { // 1 bit 81 | // ************************************************************************** 82 | // This line is really the only tight goldilocks timing in the whole program! 83 | // ************************************************************************** 84 | asm volatile ( 85 | "sbi %[port], %[bit] \n\t" // Set the output bit 86 | ".rept %[onCycles] \n\t" // Now timing actually matters. The 0-bit must be long enough to be detected but not too long or it will be a 1-bit 87 | "nop \n\t" // Execute NOPs to delay exactly the specified number of cycles 88 | ".endr \n\t" 89 | "cbi %[port], %[bit] \n\t" // Clear the output bit 90 | ".rept %[offCycles] \n\t" // Execute NOPs to delay exactly the specified number of cycles 91 | "nop \n\t" 92 | ".endr \n\t" 93 | :: 94 | [port] "I" (_SFR_IO_ADDR(PIXEL_PORT)), 95 | [bit] "I" (PIXEL_BIT), 96 | [onCycles] "I" (NS_TO_CYCLES(T0H) - 2), 97 | [offCycles] "I" (NS_TO_CYCLES(T0L) - 2) 98 | ); 99 | } // if 100 | 101 | // Note that the inter-bit gap can be as long as you want as long as it doesn't exceed the 5us reset timeout (which is A long time) 102 | // Here I have been generous and not tried to squeeze the gap tight but instead erred on the side of lots of extra time. 103 | // This has thenice side effect of avoid glitches on very long strings becuase 104 | } // sendBit() 105 | 106 | // Neopixel wants bit in highest-to-lowest order 107 | // so send highest bit (bit #7 in an 8-bit byte since they start at 0) 108 | inline void sendByte(uint8_t byte) 109 | { 110 | for (uint8_t bit = 0; bit < 8; bit++) { 111 | sendBit(byte & 0x80); 112 | byte <<= 113 | 1; // and then shift left so bit 6 moves into 7, 5 moves into 6, etc 114 | } // for 115 | } // sendByte() 116 | 117 | /* 118 | The following three functions are the public API: 119 | ledSetup() - set up the pin that is connected to the string. Call once at the begining of the program. 120 | sendPixel( r g , b ) - send a single pixel to the string. Call this once for each pixel in a frame. 121 | show() - show the recently sent pixel on the LEDs . Call once per frame. 122 | */ 123 | 124 | // Set the specified pin up as digital out 125 | 126 | void sendPixel(uint8_t r, uint8_t g, uint8_t b) { 127 | sendByte(g); // Neopixel wants colors in green then red then blue order 128 | sendByte(r); 129 | sendByte(b); 130 | } // sendPixel 131 | 132 | 133 | // ----- defines and routines from josh - End ----- 134 | 135 | void setupNeopixel() { 136 | bitSet( PIXEL_DDR , PIXEL_BIT ); 137 | } // setupNeopixel() 138 | 139 | 140 | // read data from the DMX buffer (RGB) and send it to the neopixels... 141 | void updateNeopixel(uint8_t *ptr, uint8_t pixels) { 142 | uint8_t r, g, b; 143 | 144 | // no interrupt is welcome. 145 | cli(); 146 | 147 | for (int p = 0; p < pixels; p++ ) { 148 | r = *ptr++; 149 | g = *ptr++; 150 | b = *ptr++; 151 | // send to Neopixels 152 | // sendPixel(r, g , b); 153 | sendPixel(r >> 2, g >> 2, b >> 2); 154 | } // for 155 | 156 | // interrupt may come. 157 | sei(); 158 | 159 | // Just wait long enough without sending any bots to cause the pixels to latch and display the last sent frame 160 | _delay_us((RES / 1000UL) + 1); 161 | } // updateNeopixel() 162 | 163 | // End 164 | -------------------------------------------------------------------------------- /Uno/DMX_Serial_Tx_Rx/readme.md: -------------------------------------------------------------------------------- 1 | Testing the DMX Serial library to make a transmitter and receiver 2 | -------------------------------------------------------------------------------- /Uno/DS18B20_LCD/1602_LCD_I2C_HelloWorld.ino: -------------------------------------------------------------------------------- 1 | // I2C Version 2 | 3 | #include 4 | #include // main hd44780 header 5 | #include // i2c expander i/o class header 6 | 7 | hd44780_I2Cexp lcd; // declare lcd object: auto locate & auto config expander chip 8 | 9 | void setup() 10 | { 11 | lcd.begin(16, 2); 12 | lcd.print("Hello, World!"); 13 | } 14 | 15 | void loop() {} 16 | -------------------------------------------------------------------------------- /Uno/DS18B20_LCD/1602_LCD_PINS_HelloWorld.ino: -------------------------------------------------------------------------------- 1 | // Direct Pin Version 2 | 3 | #include 4 | #include // Arduino pin i/o class header 5 | 6 | const int rs=8, en=9, db4=4, db5=5, db6=6, db7=7; 7 | 8 | hd44780_pinIO lcd(rs, en, db4, db5, db6, db7); // declare lcd object for pin control of LCD 9 | 10 | void setup() 11 | { 12 | lcd.begin(16, 2); 13 | lcd.print("Hello, World!"); 14 | lcd.print(char(226)); 15 | } 16 | 17 | void loop() {} 18 | -------------------------------------------------------------------------------- /Uno/DS18B20_LCD/DS18B20_LCD.ino: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------------- 2 | // Sketch based on LCD demonstration 3 | // by Bill Perry bperrybap@opensource.billsworld.billandterrie.com 4 | // and various DS18B20 Onewire/Dallas library code snippets 5 | // 6 | // This example code is unlicensed and is released into the public domain 7 | // 8 | // Gadget Reboot 9 | // ---------------------------------------------------------------------------- 10 | // 11 | // This sketch is for LCDs with PCF8574 backpacks/interfaces (serial I2C control) 12 | // as well as direct wiring to Arduino digital outputs (parallel control). 13 | // The "lcd" object interfaces with the I2C display 14 | // The "lcdParallel" object interfaces with the direct Arduino pin controlled display 15 | // 16 | // The DS18B20 digital temperature sensor reading is displayed in degrees C 17 | // on one LCD and in degrees F on the other LCD to demonstrate how to use the 18 | // sensor as well as the LCDs in serial or parallel mode. 19 | // 20 | // WARNING: 21 | // Use caution when using 3v only processors like arm and ESP8266 processors 22 | // when interfacing with 5v modules as not doing proper level shifting or 23 | // incorrectly hooking things up can damage the processor. 24 | // 25 | // While not all hd44780 LCD drivers use the same pinout, here is the most common: 26 | // pin 1 is the pin closest to the edge of the PCB 27 | // 1 - LCD gnd 28 | // 2 - VCC (5v) 29 | // 3 - Vo Contrast Voltage 30 | // 4 - RS Register Select (rs) 31 | // 5 - Read/Write 32 | // 6 - Enable (en) 33 | // 7 - Data 0 (db0) ---- 34 | // 8 - Data 1 (db1) |-------- Not used in 4 bit mode 35 | // 9 - Data 2 (db2) | 36 | // 10 - Data 3 (db3) ---- 37 | // 11 - Data 4 (db4) 38 | // 12 - Data 5 (db5) 39 | // 13 - Data 6 (db6) 40 | // 14 - Data 7 (db7) 41 | // 15 - Backlight Anode (+5v) 42 | // 16 - Backlight Cathode (Gnd) 43 | // 44 | // 45 | // Requires the HD44780 library for the LCD 46 | // Requires the OneWire and DallasTemperature libraries for the DS18B20 47 | 48 | #include 49 | #include // LCD hd44780 library 50 | #include // I2C expander i/o class 51 | #include // Arduino pin i/o class header 52 | #include // One Wire library 53 | #include // DS18B20 library 54 | 55 | #define ONE_WIRE_BUS 2 // DS18B20 data wire is connected to digital pin 2 56 | 57 | DeviceAddress thermometerAddress; // custom array type to hold 64 bit DS18B20 device address 58 | OneWire oneWire(ONE_WIRE_BUS); // create a oneWire instance to communicate with temperature IC 59 | DallasTemperature tempSensor(&oneWire); // pass the oneWire reference to Dallas Temperature 60 | 61 | // LCD geometry 62 | const int LCD_COLS = 16; 63 | const int LCD_ROWS = 2; 64 | 65 | // declare object for GPIO expander LCD: auto locate & auto config expander chip 66 | hd44780_I2Cexp lcd; 67 | 68 | // declare Arduino pins used for LCD direct pin control 69 | // this method does not control the backlight 70 | // note that ESP8266 based arduinos must use the Dn defines rather than 71 | // raw pin numbers. 72 | #if defined (ARDUINO_ARCH_ESP8266) 73 | const int rs = D8, en = D9, db4 = D4, db5 = D5, db6 = D6, db7 = D7; // for esp8266 devices 74 | #else 75 | const int rs = 8, en = 9, db4 = 4, db5 = 5, db6 = 6, db7 = 7; // for all other devices 76 | #endif 77 | hd44780_pinIO lcdParallel(rs, en, db4, db5, db6, db7); 78 | 79 | /* 80 | //with backlight control: 81 | // backlight control requires two additional parameters 82 | // - an additional pin to control the backlight 83 | // - backlight active level which tells the library the level 84 | // needed to turn on the backlight. 85 | // note: If the backlight control pin supports PWM, dimming can be done 86 | // using setBacklight(dimvalue); 87 | #if defined (ARDUINO_ARCH_ESP8266) 88 | const int rs = D8, en = D9, db4 = D4, db5 = D5, db6 = D6, db7 = D7, bl = D10, blLevel = HIGH; 89 | #else 90 | const int rs = 8, en = 9, db4 = 4, db5 = 5, db6 = 6, db7 = 7, bl = 10, blLevel = HIGH; 91 | #endif 92 | hd44780_pinIO lcd(rs, en, db4, db5, db6, db7, bl, blLEvel); 93 | */ 94 | 95 | void setup() 96 | { 97 | Serial.begin(9600); 98 | 99 | // initialize I2C LCD with number of columns and rows: 100 | lcd.begin(LCD_COLS, LCD_ROWS); 101 | lcd.lineWrap(); // turn on automatic line wrapping 102 | 103 | // initialize parallel LCD with number of columns and rows: 104 | lcdParallel.begin(LCD_COLS, LCD_ROWS); 105 | lcdParallel.lineWrap(); // turn on automatic line wrapping 106 | 107 | Serial.println("DS18B20 Temperature IC Test"); 108 | Serial.println("Locating devices..."); 109 | tempSensor.begin(); // initialize the temp sensor 110 | 111 | if (!tempSensor.getAddress(thermometerAddress, 0)) 112 | Serial.println("Unable to find Device."); 113 | else { 114 | Serial.print("Device 0 Address: "); 115 | printAddress(thermometerAddress); 116 | Serial.println(); 117 | } 118 | 119 | tempSensor.setResolution(thermometerAddress, 11); // set the temperature resolution (9-12) 120 | } 121 | 122 | void loop() { 123 | 124 | tempSensor.requestTemperatures(); // request temperature sample from sensor on the one wire bus 125 | displayTemp(tempSensor.getTempC(thermometerAddress)); // show temperature on LCD displays 126 | 127 | delay(500); // update readings every half a second 128 | } 129 | 130 | // display temperature on LCDs 131 | void displayTemp(float temperatureReading) { // temperature comes in as a float with 2 decimal places 132 | Serial.print("Temperature: "); 133 | 134 | // show temperature °C 135 | lcdParallel.clear(); 136 | lcdParallel.print("Temperature: "); 137 | lcdParallel.setCursor(0, 1); 138 | lcdParallel.print(temperatureReading, 1); // rounded to 1 decimal place 139 | lcdParallel.print((char)223); // degree symbol 140 | lcdParallel.print("C"); 141 | 142 | Serial.print(temperatureReading); // serial debug output 143 | Serial.print("°"); 144 | Serial.print("C "); 145 | 146 | // show temperature °F 147 | lcd.clear(); 148 | lcd.print("Temperature: "); 149 | lcd.setCursor(0, 1); 150 | lcd.print(DallasTemperature::toFahrenheit(temperatureReading), 1); // rounded to 1 decimal place 151 | lcd.print((char)223); // degree symbol 152 | lcd.print("F"); 153 | 154 | Serial.print(DallasTemperature::toFahrenheit(temperatureReading)); // serial debug output 155 | Serial.print("°"); 156 | Serial.print("F"); 157 | 158 | Serial.println(); 159 | } 160 | 161 | // print DS18B20 device address from the custom address array 162 | void printAddress(DeviceAddress deviceAddress) 163 | { 164 | for (uint8_t i = 0; i < 8; i++) 165 | { 166 | if (deviceAddress[i] < 16) Serial.print("0"); 167 | Serial.print(deviceAddress[i], HEX); 168 | } 169 | } 170 | -------------------------------------------------------------------------------- /Uno/DS18B20_LCD/DS18B20_LCD_BASIC.ino: -------------------------------------------------------------------------------- 1 | // Temperature display using the DS18B20 digital thermometer 2 | // and a 16x2 LCD display connected directly to Arduino (no serial interface) 3 | 4 | #include // LCD hd44780 library 5 | #include // Arduino pin i/o class header 6 | #include // One Wire library 7 | #include // DS18B20 library 8 | 9 | #define ONE_WIRE_BUS 2 // DS18B20 data wire is connected to digital pin 2 10 | 11 | OneWire oneWire(ONE_WIRE_BUS); // create a oneWire instance to communicate with temperature IC 12 | DallasTemperature tempSensor(&oneWire); // pass the oneWire reference to Dallas Temperature 13 | 14 | const int rs = 8, en = 9, db4 = 4, db5 = 5, db6 = 6, db7 = 7; // LCD pins on Arduino 15 | hd44780_pinIO lcd(rs, en, db4, db5, db6, db7); 16 | 17 | void setup() 18 | { 19 | lcd.begin(16, 2); // initialize the 16x2 LCD 20 | tempSensor.begin(); // initialize the temp sensor 21 | } 22 | 23 | void loop() { 24 | // request temperature sample from sensor on the one wire bus 25 | tempSensor.requestTemperatures(); 26 | float tempDegC = tempSensor.getTempCByIndex(0); 27 | float tempDegF = DallasTemperature::toFahrenheit(tempDegC); 28 | 29 | // show temperature °C 30 | lcd.clear(); 31 | lcd.print("Temp: "); 32 | lcd.print(tempDegC, 1); // rounded to 1 decimal place 33 | lcd.print((char)223); // degree symbol 34 | lcd.print("C"); 35 | 36 | // show temperature °F 37 | lcd.setCursor(0, 1); 38 | lcd.print("Temp: "); 39 | lcd.print(tempDegF, 1); // rounded to 1 decimal place 40 | lcd.print((char)223); // degree symbol 41 | lcd.print("F"); 42 | 43 | delay(1000); 44 | } 45 | 46 | -------------------------------------------------------------------------------- /Uno/DS18B20_LCD/DS18B20_LCD_Schematic.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GadgetReboot/Arduino/adf95ad05b710d7a58421f86df913644a04948d4/Uno/DS18B20_LCD/DS18B20_LCD_Schematic.jpg -------------------------------------------------------------------------------- /Uno/DS18B20_LCD/readme.md: -------------------------------------------------------------------------------- 1 | Using the DS18B20 Digital Temperature Sensor with Arduino 2 | Displaying temperature in deg C and deg F on two 1602 2x16 char LCDs 3 | One display is using straight parallel connections to Arduino 4 | The other is using a PCF8574 I2C GPIO Expander 5 | -------------------------------------------------------------------------------- /Uno/DS18B20_TFT_LCD/DS18B20 TFT LCD Schematic.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GadgetReboot/Arduino/adf95ad05b710d7a58421f86df913644a04948d4/Uno/DS18B20_TFT_LCD/DS18B20 TFT LCD Schematic.jpg -------------------------------------------------------------------------------- /Uno/DS18B20_TFT_LCD/readme.md: -------------------------------------------------------------------------------- 1 | Using a 480x320 3.5" TFT LCD from MCUFriend with Arduino Uno and a DS18B20 digital thermometer. 2 | 3 | Temperature is displayed numerically and graphically on the screen with two touch sensitive 4 | button areas to switch between deg C and deg F 5 | 6 | ### General steps to get up and running 7 | 8 | 1. Install the three required Arduino TFT LCD libraries: 9 | - [MCUFriend_kbv](https://github.com/prenticedavid/MCUFRIEND_kbv) 10 | - [Adafruit GFX](https://github.com/adafruit/Adafruit-GFX-Library) 11 | - [Adafruit TouchScreen](https://github.com/adafruit/Adafruit_TouchScreen) 12 | 13 | 2. Run the TouchScreen_Calibr_native.ino sketch from the MCUFriend_kbv library example sketches. This will auto-detect the correct pins for the X and Y plus and minus touch screen pins (YP, YM, XP, XM). Then use a small tipped stylus to click the screen and enter the next calibration menu. There will be boxes with cross hairs around the edge of the screen. Click in the center of the cross hairs to detect the edges and corners of the screen. 14 | 15 | 3. When the calibration is complete, the serial monitor will display two lines of code that can be directly copied and pasted into a sketch to configure it for this touch screen's pinouts and screen edge limits. Copy those lines into the target sketch. An example may be: 16 | 17 | const int XP=7,XM=A1,YP=A2,YM=6; //320x480 ID=0x0099 18 | 19 | const int TS_LEFT = 903, TS_RT = 163, TS_TOP = 947, TS_BOT = 165; 20 | 21 | 4. Some displays may have inverted screen colors, eg. the sketch says to draw a black rectangle but it comes out white. If this occurs, call the "invertDisplay(true)" routine from somewhere in the setup routine after initializing the screen, for example: 22 | 23 | tft.begin(ID); // initialize the Touch Screen 24 | 25 | tft.invertDisplay(true); // compensate for screens that have inverted colors 26 | 27 | This assumes you named your screen object "tft", eg. 28 | 29 | MCUFRIEND_kbv tft; // create a tft object for the Touch Screen display 30 | 31 | 5. Using these steps should allow an MCUFriend TFT LCD display to work when making these modifications to the library example sketches such as button_simple.ino 32 | -------------------------------------------------------------------------------- /Uno/DS18B20_Temp_Sensor/DS18B20_Schematic.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GadgetReboot/Arduino/adf95ad05b710d7a58421f86df913644a04948d4/Uno/DS18B20_Temp_Sensor/DS18B20_Schematic.jpg -------------------------------------------------------------------------------- /Uno/DS18B20_Temp_Sensor/DS18B20_Serial_Monitor_Only.ino: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | This is an example for reading the temperature out of a 3 | DS18B20 sensor and displaying the result in the Serial monitor 4 | of the Arduino IDE. 5 | 6 | Temperature is displayed in degrees C and F. 7 | 8 | Gadget Reboot 9 | 10 | *********************************************************************/ 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | #define ONE_WIRE_BUS 2 // DS18B20 data wire is connected to input 2 17 | 18 | DeviceAddress thermometerAddress; // custom array type to hold 64 bit device address 19 | 20 | OneWire oneWire(ONE_WIRE_BUS); // create a oneWire instance to communicate with temperature IC 21 | DallasTemperature tempSensor(&oneWire); // pass the oneWire reference to Dallas Temperature 22 | 23 | void setup() { 24 | 25 | Serial.begin(9600); 26 | 27 | Serial.println("DS18B20 Temperature IC Test"); 28 | Serial.println("Locating devices..."); 29 | tempSensor.begin(); // initialize the temp sensor 30 | 31 | if (!tempSensor.getAddress(thermometerAddress, 0)) 32 | Serial.println("Unable to find Device."); 33 | else { 34 | Serial.print("Device 0 Address: "); 35 | printAddress(thermometerAddress); 36 | Serial.println(); 37 | } 38 | 39 | tempSensor.setResolution(thermometerAddress, 9); // set the temperature resolution (9-12) 40 | } 41 | 42 | 43 | void loop() { 44 | 45 | tempSensor.requestTemperatures(); // request temperature sample from sensor on the one wire bus 46 | displayTemp(tempSensor.getTempC(thermometerAddress)); // show temperature on OLED display 47 | 48 | delay(500); // update readings every half a second 49 | } 50 | 51 | void displayTemp(float temperatureReading) { // temperature comes in as a float with 2 decimal places 52 | 53 | // show temperature °C 54 | Serial.print(temperatureReading); // serial debug output 55 | Serial.print("°"); 56 | Serial.print("C "); 57 | 58 | // show temperature °F 59 | Serial.print(DallasTemperature::toFahrenheit(temperatureReading)); // serial debug output 60 | Serial.print("°"); 61 | Serial.println("F"); 62 | } 63 | 64 | 65 | // print device address from the address array 66 | void printAddress(DeviceAddress deviceAddress) 67 | { 68 | for (uint8_t i = 0; i < 8; i++) 69 | { 70 | if (deviceAddress[i] < 16) Serial.print("0"); 71 | Serial.print(deviceAddress[i], HEX); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /Uno/DS18B20_Temp_Sensor/DS18B20_Temp_Sensor_OLED.ino: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | This is an example for reading the temperature out of a 3 | DS18B20 sensor and displaying the result on an SSD1306 4 | 128x64 OLED display over the I2C bus. 5 | 6 | Temperature is displayed in degrees C and F. 7 | 8 | Gadget Reboot 9 | 10 | *********************************************************************/ 11 | 12 | #include 13 | #include 14 | #include 15 | #include 16 | 17 | #define ONE_WIRE_BUS 2 // DS18B20 data wire is connected to input 2 18 | #define OLED_RESET 4 // Adafruit needs this but we don't use for I2C 19 | 20 | DeviceAddress thermometerAddress; // custom array type to hold 64 bit device address 21 | 22 | Adafruit_SSD1306 display(OLED_RESET); // create a display instance 23 | OneWire oneWire(ONE_WIRE_BUS); // create a oneWire instance to communicate with temperature IC 24 | DallasTemperature tempSensor(&oneWire); // pass the oneWire reference to Dallas Temperature 25 | 26 | 27 | void setup() { 28 | 29 | Serial.begin(9600); 30 | 31 | display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // initialize with the I2C address of the display 32 | display.clearDisplay(); // clear the display buffer 33 | display.display(); // update display 34 | 35 | Serial.println("DS18B20 Temperature IC Test"); 36 | Serial.println("Locating devices..."); 37 | tempSensor.begin(); // initialize the temp sensor 38 | 39 | if (!tempSensor.getAddress(thermometerAddress, 0)) 40 | Serial.println("Unable to find Device."); 41 | else { 42 | Serial.print("Device 0 Address: "); 43 | printAddress(thermometerAddress); 44 | Serial.println(); 45 | } 46 | 47 | tempSensor.setResolution(thermometerAddress, 11); // set the temperature resolution (9-12) 48 | } 49 | 50 | 51 | void loop() { 52 | 53 | tempSensor.requestTemperatures(); // request temperature sample from sensor on the one wire bus 54 | displayTemp(tempSensor.getTempC(thermometerAddress)); // show temperature on OLED display 55 | 56 | delay(500); // update readings every half a second 57 | } 58 | 59 | void displayTemp(float temperatureReading) { // temperature comes in as a float with 2 decimal places 60 | 61 | // set up OLED text size and print the temperature data 62 | display.clearDisplay(); 63 | display.setTextSize(2); 64 | display.setTextColor(WHITE); 65 | display.setCursor(0, 0); 66 | display.println("Temp:"); 67 | 68 | // show temperature °C 69 | display.print(temperatureReading, 1); // rounded to 1 decimal place 70 | display.print((char)247); // degree symbol 71 | display.println("C"); 72 | Serial.print(temperatureReading); // serial debug output 73 | Serial.print("°"); 74 | Serial.print("C "); 75 | 76 | // show temperature °F 77 | display.print(DallasTemperature::toFahrenheit(temperatureReading), 1); // rounded to 1 decimal place 78 | display.print((char)247); // degree symbol 79 | display.println("F"); 80 | Serial.print(DallasTemperature::toFahrenheit(temperatureReading)); // serial debug output 81 | Serial.print("°"); 82 | Serial.println("F"); 83 | 84 | display.display(); // update the OLED display with all the new text 85 | } 86 | 87 | 88 | // print device address from the address array 89 | void printAddress(DeviceAddress deviceAddress) 90 | { 91 | for (uint8_t i = 0; i < 8; i++) 92 | { 93 | if (deviceAddress[i] < 16) Serial.print("0"); 94 | Serial.print(deviceAddress[i], HEX); 95 | } 96 | } 97 | 98 | 99 | 100 | -------------------------------------------------------------------------------- /Uno/DS18B20_Temp_Sensor/readme.md: -------------------------------------------------------------------------------- 1 | Using the DS18B20 one wire temperature sensor to report temperature 2 | in degrees C and F on serial monitor and 128x64 OLED display. 3 | -------------------------------------------------------------------------------- /Uno/I2C_Scanner/I2C_Scanner.ino: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | This is an example for scanning the I2C bus 7-bit address range 3 | and reporting all addresses that have functioning devices 4 | attached. 5 | 6 | Based on several I2C scanner programs found at: 7 | https://playground.arduino.cc/Main/I2cScanner 8 | 9 | Addresses scanned: 0x08 to 0x77 10 | Reserved address ranges NOT scanned: 0000xxx and 1111xxx 11 | 12 | For more information about I2C specifications, refer to: 13 | https://www.nxp.com/docs/en/user-guide/UM10204.pdf 14 | 15 | For a list of many known I2C device addresses: 16 | https://learn.adafruit.com/i2c-addresses/the-list 17 | 18 | This code is released to the public domain. 19 | Gadget Reboot 20 | 21 | *********************************************************************/ 22 | 23 | #include 24 | 25 | byte errorResult; // error code returned by I2C Wire.endTransmission() 26 | byte i2c_addr; // I2C address being pinged 27 | byte lowerAddress = 0x08; // I2C lowest valid address in range 28 | byte upperAddress = 0x77; // I2C highest valid address in range 29 | byte numDevices; // how many devices were located on I2C bus 30 | 31 | void setup() { 32 | 33 | Wire.begin(); // I2C init 34 | Serial.begin(9600); // search results show up in serial monitor 35 | 36 | } 37 | 38 | 39 | void loop() { 40 | 41 | Serial.print("Scanning I2C 7-bit address range 0x"); 42 | if (lowerAddress < 0x10) // pad single digit addresses with a leading "0" 43 | Serial.print("0"); 44 | Serial.print(lowerAddress, HEX); 45 | Serial.print(" to 0x"); 46 | Serial.print(upperAddress, HEX); 47 | Serial.println("."); 48 | 49 | numDevices = 0; 50 | 51 | for (i2c_addr = lowerAddress; i2c_addr <= upperAddress; i2c_addr++ ) // loop through all valid I2C addresses 52 | { 53 | Wire.beginTransmission(i2c_addr); // initiate communication at current address 54 | errorResult = Wire.endTransmission(); // if a device is present, it will send an ack and "0" will be returned from function 55 | 56 | if (errorResult == 0) // "0" means a device at current address has acknowledged the serial communication 57 | { 58 | Serial.print("I2C device found at address 0x"); 59 | 60 | if (i2c_addr < 0x10) // pad single digit addresses with a leading "0" 61 | Serial.print("0"); 62 | 63 | Serial.println(i2c_addr, HEX); // display the address on the serial monitor when a device is found 64 | numDevices++; 65 | } 66 | } 67 | 68 | Serial.print("Scan complete. Devices found: "); 69 | Serial.println(numDevices); 70 | Serial.println(); 71 | 72 | delay(10000); // wait 10 seconds and scan again to detect on-the-fly bus changes 73 | } 74 | -------------------------------------------------------------------------------- /Uno/I2C_Scanner/readme.md: -------------------------------------------------------------------------------- 1 | Scan all valid 7 bit I2C addresses from 0x08 to 0x77 2 | and report addresses that receive an ACK, 3 | indicating a device is present at that address. 4 | -------------------------------------------------------------------------------- /Uno/NeoPixel/Chaser.ino: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------------- 2 | // How to use the FastLED library for simple control of WS2812B RGB LEDs 3 | // Two lines are drawn, one Green and one Blue, each 3 LEDs in length 4 | // Each line moves end to end along the strip at slightly different rates 5 | // If the pot is moved high enough from the ground terminal, the green 6 | // line can be moved manually by the pot wiper position along the strip. 7 | // 8 | // This example code is unlicensed and is released into the public domain 9 | // 10 | // Gadget Reboot 11 | // ---------------------------------------------------------------------------- 12 | 13 | #include 14 | 15 | //#define DEBUG 16 | #define NUM_LEDS 60 17 | #define DATA_PIN 2 18 | #define COLOR_ORDER GRB 19 | #define LED_TYPE WS2812B 20 | #define POT A0 21 | 22 | // Define the array of leds 23 | CRGB leds[NUM_LEDS]; 24 | 25 | int onePos = 2; 26 | int twoPos = 2; 27 | byte oneDir = 0; 28 | byte twoDir = 0; 29 | 30 | void setup() { 31 | #ifdef DEBUG 32 | Serial.begin(9600); 33 | #endif 34 | 35 | FastLED.addLeds(leds, NUM_LEDS); 36 | 37 | } 38 | 39 | void loop() { 40 | 41 | // if pot is above ground, override green line position based on pot position 42 | if (analogRead(POT) > 10) { 43 | onePos = map(analogRead(POT), 0, 1023, 0, NUM_LEDS - 1); 44 | } 45 | 46 | #ifdef DEBUG 47 | Serial.print("Potentiometer: "); 48 | Serial.println(analogRead(POT)); 49 | #endif 50 | 51 | // turn on the green and blue LEDs to draw the current 52 | // position of each line along the strip 53 | leds[onePos] = CRGB(0, 255, 0); 54 | leds[max(onePos - 1, 0)] = CRGB(0, 255, 0); 55 | leds[min(onePos + 1, NUM_LEDS - 1)] = CRGB(0, 255, 0); 56 | 57 | leds[twoPos] = CRGB(0, 0, 255); 58 | leds[max(twoPos - 1, 0)] = CRGB(0, 0, 255); 59 | leds[min(twoPos + 1, NUM_LEDS - 1)] = CRGB(0, 0, 255); 60 | 61 | FastLED.show(); 62 | delay(150); 63 | 64 | // turn all LEDs off so they can be re-drawn on the next loop 65 | // in the next calculated position 66 | leds[onePos] = CRGB(0, 0, 0); 67 | leds[max(onePos - 1, 0)] = CRGB(0, 0, 0); 68 | leds[min(onePos + 1, NUM_LEDS - 1)] = CRGB(0, 0, 0); 69 | 70 | leds[twoPos] = CRGB(0, 0, 0); 71 | leds[max(twoPos - 1, 0)] = CRGB(0, 0, 0); 72 | leds[min(twoPos + 1, NUM_LEDS - 1)] = CRGB(0, 0, 0); 73 | 74 | FastLED.show(); 75 | 76 | #ifdef DEBUG 77 | Serial.print("One Direction: "); 78 | Serial.println(oneDir); 79 | Serial.print("One Position: "); 80 | Serial.println(onePos); 81 | //Serial.println(); 82 | 83 | Serial.print("Two Direction: "); 84 | Serial.println(twoDir); 85 | Serial.print("Two Position: "); 86 | Serial.println(twoPos); 87 | Serial.println(); 88 | #endif 89 | 90 | // calculate the next position of each LED line by advancing the 91 | // LED position in the forward or reverse direction as required. 92 | // if the line reaches the end of the LED strip, it is time to 93 | // change its direction. 94 | if (oneDir == 0) { // if going forward 95 | onePos += 4; 96 | if (onePos >= NUM_LEDS) { 97 | onePos = NUM_LEDS - 1; 98 | oneDir = 1; // go in reverse direction 99 | } 100 | } 101 | // else { //if going reverse 102 | if (oneDir == 1) { 103 | onePos -= 4; 104 | if (onePos <= 0) { 105 | onePos = 0; 106 | oneDir = 0; // go in forward direction 107 | } 108 | } 109 | 110 | if (twoDir == 0) { // if going forward 111 | twoPos += 3; 112 | if (twoPos >= NUM_LEDS) { 113 | twoPos = NUM_LEDS - 1; 114 | twoDir = 1; // go in reverse direction 115 | } 116 | } 117 | //else { //if going reverse 118 | if (twoDir == 1) { 119 | twoPos -= 3; 120 | if (twoPos <= 0) { 121 | twoPos = 0; 122 | twoDir = 0; // go in forward direction 123 | } 124 | } 125 | 126 | } 127 | -------------------------------------------------------------------------------- /Uno/NeoPixel/NeoPixel_60_Schematic.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GadgetReboot/Arduino/adf95ad05b710d7a58421f86df913644a04948d4/Uno/NeoPixel/NeoPixel_60_Schematic.jpg -------------------------------------------------------------------------------- /Uno/NeoPixel/NeoPixel_Basics.ino: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------------- 2 | // How to use the FastLED library for simple control of WS2812B RGB LEDs 3 | // 4 | // This example code is unlicensed and is released into the public domain 5 | // 6 | // Gadget Reboot 7 | // ---------------------------------------------------------------------------- 8 | 9 | #include 10 | 11 | #define LED_TYPE WS2812B // type of RGB LEDs 12 | #define COLOR_ORDER GRB // sequence of colors in data stream 13 | #define NUM_LEDS 60 // 60 LEDs numbered [0..59] 14 | #define DATA_PIN 2 // LED data pin 15 | #define BRIGHTNESS 200 // brightness range [off..on] = [0..255] 16 | 17 | // Define the array of RGB control data for each LED 18 | CRGB leds[NUM_LEDS]; 19 | 20 | void setup() { 21 | 22 | // initialize library using CRGB LED array 23 | FastLED.addLeds(leds, NUM_LEDS); 24 | 25 | } 26 | 27 | void loop() { 28 | 29 | // configure some LEDs by direct RGB level setting 30 | leds[0] = CRGB(255, 0, 0); 31 | leds[1] = CRGB(0, 255, 0); 32 | leds[2] = CRGB(0, 0, 255); 33 | 34 | leds[3].r = 128; 35 | leds[3].g = 75; 36 | leds[3].b = 170; 37 | 38 | leds[4].setRGB(50, 100, 150); 39 | leds[5] = 0x08FFA7; 40 | 41 | // use a routine to fill a block of LEDs with a fixed color 42 | fill_solid( &(leds[6]), 5 /*number of leds*/, CRGB(100, 20, 130)); 43 | 44 | // use a routine to fill a block of LEDs with a rainbow 45 | fill_rainbow( &(leds[11]), 10 /*number of leds*/, 1 /*starting hue*/); 46 | 47 | // configure some LEDs using hue, saturation, brightness 48 | leds[39] = CHSV( HUE_PURPLE, 255, 255); 49 | leds[38] = CHSV( HUE_PURPLE, 150, 255); 50 | leds[37] = CHSV( HUE_GREEN, 255, 255); 51 | leds[36] = CHSV( HUE_GREEN, 150, 255); 52 | leds[35] = CHSV( HUE_ORANGE, 255, 255); 53 | leds[34] = CHSV( HUE_ORANGE, 150, 255); 54 | 55 | // configure some LEDs using predefined RGB web color names 56 | leds[59] = CRGB::White; 57 | leds[58] = CRGB::HotPink; 58 | leds[57] = CRGB::DarkOrange; 59 | leds[56] = CRGB::Purple; 60 | leds[55] = CRGB::YellowGreen; 61 | leds[54] = CRGB::FireBrick; 62 | 63 | // optionally set the overall brightness for all LEDs 64 | FastLED.setBrightness(BRIGHTNESS); 65 | 66 | // activate all changes to LEDs 67 | FastLED.show(); 68 | 69 | // wait a while, then gradually reduce brightness to 0 70 | delay(1000); 71 | 72 | FastLED.setBrightness(150); 73 | FastLED.show(); 74 | delay(1000); 75 | 76 | FastLED.setBrightness(75); 77 | FastLED.show(); 78 | delay(1000); 79 | 80 | FastLED.setBrightness(10); 81 | FastLED.show(); 82 | delay(1000); 83 | 84 | FastLED.setBrightness(5); 85 | FastLED.show(); 86 | delay(1000); 87 | 88 | FastLED.setBrightness(0); 89 | FastLED.show(); 90 | delay(1000); 91 | 92 | } 93 | -------------------------------------------------------------------------------- /Uno/NeoPixel/NeoPixel_White_Test.ino: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------------- 2 | // How to use the FastLED library for simple control of WS2812B RGB LEDs 3 | // Quick and dirty test to turn one LED on fully white, all LEDs off, 4 | // all LEDs on fully white, then repeat a fill pattern where all LEDs are 5 | // turned on, then off, one by one. 6 | // 7 | // Used for current draw measurements to see how much current a strip needs. 8 | // 9 | // This example code is unlicensed and is released into the public domain 10 | // 11 | // Gadget Reboot 12 | // ---------------------------------------------------------------------------- 13 | 14 | 15 | #include 16 | 17 | // How many leds in your strip? 18 | #define NUM_LEDS 60 19 | 20 | // For led chips like Neopixels, which have a data line, ground, and power, you just 21 | // need to define DATA_PIN. For led chipsets that are SPI based (four wires - data, clock, 22 | // ground, and power), like the LPD8806 define both DATA_PIN and CLOCK_PIN 23 | #define DATA_PIN 2 24 | #define CLOCK_PIN 13 25 | 26 | // Define the array of leds 27 | CRGB leds[NUM_LEDS]; 28 | 29 | void setup() { 30 | Serial.begin(9600); 31 | // Uncomment/edit one of the following lines for your leds arrangement. 32 | // FastLED.addLeds(leds, NUM_LEDS); 33 | // FastLED.addLeds(leds, NUM_LEDS); 34 | // FastLED.addLeds(leds, NUM_LEDS); 35 | // FastLED.addLeds(leds, NUM_LEDS); 36 | // FastLED.addLeds(leds, NUM_LEDS); 37 | FastLED.addLeds(leds, NUM_LEDS); 38 | //FastLED.addLeds(leds, NUM_LEDS); 39 | // FastLED.addLeds(leds, NUM_LEDS); 40 | // FastLED.addLeds(leds, NUM_LEDS); 41 | // FastLED.addLeds(leds, NUM_LEDS); 42 | // FastLED.addLeds(leds, NUM_LEDS); 43 | // FastLED.addLeds(leds, NUM_LEDS); 44 | 45 | // FastLED.addLeds(leds, NUM_LEDS); 46 | // FastLED.addLeds(leds, NUM_LEDS); 47 | // FastLED.addLeds(leds, NUM_LEDS); 48 | // FastLED.addLeds(leds, NUM_LEDS); 49 | // FastLED.addLeds(leds, NUM_LEDS); 50 | // FastLED.addLeds(leds, NUM_LEDS); 51 | 52 | // FastLED.addLeds(leds, NUM_LEDS); 53 | // FastLED.addLeds(leds, NUM_LEDS); 54 | // FastLED.addLeds(leds, NUM_LEDS); 55 | // FastLED.addLeds(leds, NUM_LEDS); 56 | // FastLED.addLeds(leds, NUM_LEDS); 57 | // FastLED.addLeds(leds, NUM_LEDS); 58 | 59 | } 60 | 61 | void loop() { 62 | 63 | Serial.print("Brightness: "); 64 | Serial.println(255); 65 | FastLED.setBrightness( 255 ); 66 | 67 | Serial.println("Testing one white LED at full brightness..."); 68 | leds[0] = CRGB::White; 69 | FastLED.show(); 70 | 71 | delay(5000); 72 | 73 | Serial.println("Testing all LEDs at zero brightness..."); 74 | leds[0] = CRGB::Black; 75 | FastLED.show(); 76 | 77 | delay(5000); 78 | 79 | Serial.println("Testing all white LEDs at full brightness..."); 80 | for (int whiteLed = 0; whiteLed < NUM_LEDS; whiteLed++) { 81 | leds[whiteLed] = CRGB::White; 82 | } 83 | FastLED.show(); 84 | 85 | delay(5000); 86 | 87 | for (int whiteLed = (NUM_LEDS - 1); whiteLed >= 0; whiteLed--) { 88 | leds[whiteLed] = CRGB::Black; 89 | } 90 | FastLED.show(); 91 | 92 | while (1) { 93 | for (int whiteLed = 0; whiteLed < NUM_LEDS; whiteLed++) { 94 | // Turn the LED on, then pause 95 | //Serial.println("Red On"); 96 | leds[whiteLed] = CRGB::White; 97 | FastLED.show(); 98 | delay(20); 99 | } 100 | 101 | for (int whiteLed = (NUM_LEDS - 1); whiteLed >= 0; whiteLed--) { 102 | // Now turn the LED off, then pause 103 | // Serial.println("Red Off"); 104 | leds[whiteLed] = CRGB::Black; 105 | FastLED.show(); 106 | delay(20); 107 | } 108 | } 109 | 110 | } 111 | -------------------------------------------------------------------------------- /Uno/NeoPixel/readme.md: -------------------------------------------------------------------------------- 1 | Demo sketches for controlling the WS2812B NeoPixels 2 | -------------------------------------------------------------------------------- /Uno/NeoPixel_Tiles/NeoPixel_Tile_Schematic.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GadgetReboot/Arduino/adf95ad05b710d7a58421f86df913644a04948d4/Uno/NeoPixel_Tiles/NeoPixel_Tile_Schematic.jpg -------------------------------------------------------------------------------- /Uno/NeoPixel_Tiles/readme.md: -------------------------------------------------------------------------------- 1 | Using tiles of WS2812 NeoPixels to create a matrix display for text and graphics. 2 | -------------------------------------------------------------------------------- /Uno/NixiePrint/NixiePrint.ino: -------------------------------------------------------------------------------- 1 | 2 | // nixiePrint - takes a 4 digit integer and prints the 3 | // individual digits on 4 Nixie tubes with 4 | // a PCF8574 GPIO Expander 5 | // 6 | // Gadget Reboot, 2018 7 | 8 | #include 9 | 10 | // PRINTBIN macro taken from a post by zhomeslice: http://forum.arduino.cc/index.php?topic=475435.0 11 | // prints a binary number on serial monitor with leading 0 padding 12 | #define PRINTBIN(Num) for (uint32_t t = (1UL<< (sizeof(Num)*8)-1); t; t >>= 1) Serial.write(Num & t ? '1' : '0'); // Prints a binary number with leading zeros (Automatic Handling) 13 | 14 | 15 | int addr1 = 0x20; // PCF8574 device 1 16 | int addr2 = 0x21; // PCF8574 device 2 17 | int blank = 2; // input switch to blank display when low 18 | 19 | void setup() { 20 | Serial.begin(9600); 21 | pinMode(blank, INPUT_PULLUP); // use digital pin 2 to GND to blank display 22 | 23 | // I2C init 24 | Wire.begin(); 25 | 26 | // Turn off all Nixie displays by writing "1111" to all driver BCD inputs 27 | Wire.beginTransmission(addr1); 28 | Wire.write(0xFF); 29 | Wire.endTransmission(); 30 | 31 | Wire.beginTransmission(addr2); 32 | Wire.write(0xFF); 33 | Wire.endTransmission(); 34 | 35 | Serial.println(); 36 | Serial.println("Nixie Display 4 Digit Counter"); 37 | Serial.println(); 38 | } 39 | 40 | 41 | void loop() { 42 | 43 | for (int i = 0; i < 9999; i++) { 44 | Serial.print("Counter: "); // show the count on serial monitor in decimal 45 | Serial.println(i); 46 | nixiePrint(i, !digitalRead(blank)); // print the counter on the Nixie display, or blank display 47 | delay(200); 48 | } 49 | } 50 | 51 | 52 | //------------------------------------------------------------------------- 53 | // nixiePrint - takes a 4 digit integer and separates out the digits 54 | // to send to Nixie tubes 55 | //------------------------------------------------------------------------- 56 | void nixiePrint(int number, bool blanking) { 57 | byte ones, // separated out digits from input integer 58 | tens, 59 | hund, 60 | thou; 61 | byte lsb, // output BCD data for four Nixie drivers 62 | msb; 63 | 64 | ones = number % 10; // the result of (a number mod 10) is the least significant digit of the number. 65 | tens = (number / 10) % 10; // then dividing by 10 will shift the decimal so the next 66 | hund = (number / 100) % 10; // digit can be found, etc. 67 | thou = (number / 1000) % 10; 68 | 69 | // blank leading zeroes for numbers by setting Nixie driver DCBA inputs to "1111" 70 | // eg. instead of displaying "0049", just display "49" with the left digits turned off 71 | if (number < 10) { // if we only have one digit, blank the tens 72 | tens = 0xFF; 73 | } 74 | if (number < 100) { // if we only have two digits or less, blank the hundreds 75 | hund = 0xFF; 76 | } 77 | if (number < 1000) { // if we only have three digits or less, blank the thousands 78 | thou = 0xFF; 79 | } 80 | 81 | // combine the separate 4 bit digits into the two 8 bit LSB/MSB bytes to go to the GPIO expander 82 | // LSB: 7..4 = ones 3..0 = tens 83 | // MSB: 7..4 = hundreds 3..0 = thousands 84 | // to get the ones into the upper 4 bits of the byte, a left shift occurs 4 times to move the bits 85 | // then that is "or"ed with the tens, which is already in the lower 4 bit position so the final byte 86 | // has everything in the right place. 87 | // the tens must be masked with 0x0F, where the "F" contains the valid 4 bit "tens" data and the "0" 88 | // is forced into any bits that don't contain valid data. A "0" is required for the "or"ing to work 89 | 90 | lsb = (ones << 4) | (0x0F & tens); // place "tens" in lower 4 bits and "ones" in upper 4 bits of LSB data 91 | msb = (hund << 4) | (0x0F & thou); // place "thou" in lower 4 bits and "hund" in upper 4 bits of MSB data 92 | 93 | // if the display is blanked, force all 1's to the Nixie control inputs 94 | // to disable all outputs on compatible BCD drivers. If the driver does 95 | // not support blanking, the datasheet will detail the display behaviour 96 | // for an input of DCBA = 1111 97 | if (blanking == true) { 98 | lsb = 0xFF; 99 | msb = 0xFF; 100 | Serial.println("Nixie display is blanked..."); 101 | } 102 | 103 | 104 | // show the count on serial monitor in binary to confirm DCBA data 105 | // show the exact DCBA data going out to Nixie tubes (counter, or blanking override) 106 | 107 | Serial.print("Ones: "); 108 | PRINTBIN(ones); 109 | Serial.print(" "); 110 | 111 | Serial.print("Tens: "); 112 | PRINTBIN(tens); 113 | Serial.print(" "); 114 | 115 | Serial.print("LSB: "); 116 | PRINTBIN(lsb); 117 | Serial.println(); 118 | 119 | 120 | Serial.print("Hund: "); 121 | PRINTBIN(hund); 122 | Serial.print(" "); 123 | 124 | Serial.print("Thou: "); 125 | PRINTBIN(thou); 126 | Serial.print(" "); 127 | 128 | Serial.print("MSB: "); 129 | PRINTBIN(msb); 130 | Serial.println(); 131 | 132 | Serial.println(); 133 | 134 | 135 | // Send the LSB 8 bits out to "ones" and "tens" Nixie tubes on GPIO expander 136 | Wire.beginTransmission(addr1); 137 | Wire.write(lsb); 138 | Wire.endTransmission(); 139 | 140 | // Send the MSB 8 bits out to "hund" and "thou" Nixie tubes on GPIO expander 141 | Wire.beginTransmission(addr2); 142 | Wire.write(msb); 143 | Wire.endTransmission(); 144 | 145 | 146 | } 147 | 148 | -------------------------------------------------------------------------------- /Uno/NixiePrint/readme.md: -------------------------------------------------------------------------------- 1 | A sketch to display a 4 digit integer counter on a 4 digit Nixie tube display 2 | -------------------------------------------------------------------------------- /Uno/Oscilloscope_XY_PWM_Tutorial/readme.md: -------------------------------------------------------------------------------- 1 | # Arduino Scope XY Test 2 | Using an Arduino to draw simple Oscilloscope XY art using PWM. 3 | 4 | The Arduino Uno sketch is contained in file scope_XY_Test.ino 5 | 6 | This Arduino project is a modification of the original found at 7 | http://www.johngineer.com/blog/?p=648 8 | 9 | The original graphic was enhanced, a simple square graphic was added, 10 | and by commenting out various sections and enabling others, either of the 11 | three graphics can be generated, or a slideshow of all three can be 12 | played back on the oscilloscope. 13 | -------------------------------------------------------------------------------- /Uno/Oscilloscope_XY_PWM_Tutorial/scope_XY_Test.ino: -------------------------------------------------------------------------------- 1 | /* 2 | Oscilloscope Christmas Tree 3 | 4 | Created: Dec 10, 2011 5 | 6 | Author: John M. De Cristofaro 7 | 8 | License: This code CC-BY-SA 3.0 and is unsupported. 9 | (see creativecommons.org/licenses for info) 10 | 11 | */ 12 | 13 | /* **************************************************************************** 14 | Fritzing is here: 15 | 16 | http://www.flickr.com/photos/johngineer/6496005491/sizes/z/in/photostream/ 17 | 18 | in case you can't see the image, the following circuit is on both PWM ports 19 | 20 | R 21 | PWM OUT ----/\/\/\-----+------------ OUTPUT 22 | | 23 | === C 24 | | 25 | GND 26 | 27 | R = 10k 28 | C = 0.1uF 29 | 30 | Use of a 16Mhz xtal/ceramic resonator is strongly suggested. 31 | 32 | **************************************************************************** */ 33 | 34 | #define TRACE_DELAY 2500 // trace delay in uS. making this longer will 35 | // result in a straighter drawing, but slower 36 | // refresh rate. making it too short will result 37 | // in an angular blob. 38 | 39 | #define NUM_POINTS 19 // our tree is defined by 19 x/y coord. pairs 40 | #define X 6 // attach scope channel 1 (X) to pin 6 41 | #define Y 5 // attach scope channel 2 (y) to pin 5 42 | 43 | //Extra constants added for experimentation with other image drawings 44 | #define NUM_POINTS1 4 // Square shape, number of points 45 | #define NUM_POINTS2 35 // Tree with garland added, number of points 46 | #define TRACE_DELAY1 5000 // Experimentally tweaked delay 47 | #define TRACE_DELAY2 2700 // Experimentally tweaked delay 48 | #define Display_Count 20 // How many times to draw an image before switching to next image when viewing all three 49 | 50 | // x coords for drawing the tree (in rough clockwise order, from bottom) 51 | unsigned char x_points[NUM_POINTS] = { 110, 110, 50, 80, 65, 95, 80, 110, 95, 125, 155, 140, 170, 155, 185, 170, 200, 140, 140 }; 52 | // y coords 53 | unsigned char y_points[NUM_POINTS] = { 15, 35, 35, 85, 85, 135, 135, 185, 185, 235, 185, 185, 135, 135, 85, 85, 35, 35, 15 }; 54 | 55 | //Extra coordinate pairs added for experimentation with other image drawings 56 | //Coordinates of box 57 | unsigned char x1_points[NUM_POINTS1] = { 0, 0, 255, 255 }; 58 | unsigned char y1_points[NUM_POINTS1] = { 0, 255, 255, 0 }; 59 | //Coordinates of tree with garland 60 | unsigned char x2_points[NUM_POINTS2] = { 110, 110, 50, 80, 65, 95, 80, 110, 95, 125, 155, 140, 170, 155, 185, 170, 200, 140, 140, 110, 110, 50, 170, 50, 80, 155, 80, 65, 95, 140, 95, 65, 80, 50, 110 }; 61 | unsigned char y2_points[NUM_POINTS2] = { 15, 35, 35, 85, 85, 135, 135, 185, 185, 235, 185, 185, 135, 135, 85, 85, 35, 35, 15, 15, 35, 35, 85, 35, 85, 135, 85, 85, 135, 185, 135, 85, 85, 35, 35 }; 62 | 63 | 64 | void setup() 65 | { 66 | pinMode(X, OUTPUT); 67 | pinMode(Y, OUTPUT); 68 | 69 | // The following sets the PWM clock to maximum on the Arduino(no CPU clock division) 70 | // DO NOT CHANGE THESE UNLESS YOU KNOW WHAT YOU ARE DOING! 71 | 72 | TCCR0A = ( 1 << COM0A1 | 0 << COM0A0 | // clear OC0A on compare match (hi-lo PWM) 73 | 1 << COM0B1 | 0 << COM0B0 | // clear OC0B on compare match (hi-lo PWM) 74 | 1 << WGM01 | 1 << WGM00); // set PWM lines at 0xFF 75 | 76 | TCCR0B = ( 0 << FOC0A | 0 << FOC0B | // no force compare match 77 | 0 << WGM02 | // set PWM lines at 0xFF 78 | 0 << CS02 | 0 << CS01 | // use system clock (no divider) 79 | 1 << CS00 ); 80 | 81 | TIMSK0 = ( 0 << OCIE0B | 0 << TOIE0 | 82 | 0 << OCIE0A ); 83 | 84 | } 85 | 86 | // To switch between the original tree, square box, or tree with garland, 87 | // uncomment the desired void loop section and comment out the other void loops 88 | // Only one "void loop" block can be active in the code at a time. 89 | 90 | /* Uncomment this block to draw the original tree and comment out the other void loops 91 | // Original Tree 92 | void loop() 93 | { 94 | unsigned char t; 95 | { 96 | for(t = 0; t < NUM_POINTS; t++) // run through the points in x & y 97 | { 98 | analogWrite(X, x_points[t]); 99 | analogWrite(Y, y_points[t]); 100 | delayMicroseconds(TRACE_DELAY); // wait TRACE_DELAY microseconds 101 | } 102 | } 103 | } 104 | */ 105 | 106 | /* Uncomment this block to draw the square box and comment out the other void loops 107 | // Square Box 108 | void loop() 109 | { 110 | unsigned char t; 111 | { 112 | for(t = 0; t < NUM_POINTS1; t++) // run through the points in x & y 113 | { 114 | analogWrite(X, x1_points[t]); 115 | analogWrite(Y, y1_points[t]); 116 | delayMicroseconds(TRACE_DELAY1); // wait TRACE_DELAY microseconds 117 | } 118 | } 119 | } 120 | */ 121 | 122 | ///* Uncomment this block to draw the tree with garland and comment out the other void loops 123 | // Tree with Garland 124 | void loop() 125 | { 126 | unsigned char t; 127 | { 128 | for(t = 0; t < NUM_POINTS2; t++) // run through the points in x & y 129 | { 130 | analogWrite(X, x2_points[t]); 131 | analogWrite(Y, y2_points[t]); 132 | delayMicroseconds(TRACE_DELAY2); // wait TRACE_DELAY microseconds 133 | } 134 | } 135 | } 136 | //*/ 137 | 138 | /* Uncomment this block to cycle through all three drawings and comment out the other void loops 139 | // All three drawings displayed in sequence 140 | void loop() 141 | { 142 | unsigned char display_duration_counter; 143 | { 144 | for (display_duration_counter = 0; display_duration_counter < Display_Count; display_duration_counter++) // display square box this many times 145 | { 146 | unsigned char t; 147 | { 148 | for (t = 0; t < NUM_POINTS1; t++) // run through the points in x & y 149 | { 150 | analogWrite(X, x1_points[t]); 151 | analogWrite(Y, y1_points[t]); 152 | delayMicroseconds(TRACE_DELAY1); // wait TRACE_DELAY microseconds 153 | } 154 | } 155 | } 156 | 157 | for (display_duration_counter = 0; display_duration_counter < Display_Count; display_duration_counter++) // display tree this many times 158 | { 159 | unsigned char t; 160 | { 161 | for (t = 0; t < NUM_POINTS; t++) // run through the points in x & y 162 | { 163 | analogWrite(X, x_points[t]); 164 | analogWrite(Y, y_points[t]); 165 | delayMicroseconds(TRACE_DELAY); // wait TRACE_DELAY microseconds 166 | } 167 | } 168 | } 169 | 170 | for (display_duration_counter = 0; display_duration_counter < Display_Count; display_duration_counter++) // display tree with garland this many times 171 | { 172 | unsigned char t; 173 | { 174 | for (t = 0; t < NUM_POINTS2; t++) // run through the points in x & y 175 | { 176 | analogWrite(X, x2_points[t]); 177 | analogWrite(Y, y2_points[t]); 178 | delayMicroseconds(TRACE_DELAY2); // wait TRACE_DELAY microseconds 179 | } 180 | } 181 | } 182 | } 183 | } 184 | */ 185 | 186 | 187 | -------------------------------------------------------------------------------- /Uno/PCF8574/PCF8574.ino: -------------------------------------------------------------------------------- 1 | 2 | // PCF8574 Multiple I2C device access demo 3 | // Gadget Reboot, 2018 4 | 5 | #include 6 | 7 | int addr1 = 0x20; // PCF8574 device 1 8 | int addr2 = 0x21; // PCF8574 device 2 9 | int LED_Pattern = 0xFFFE; // LED Sequence Start pattern, one LED on 10 | bool ISR_FLAG = false; // Interrupt triggered flag 11 | 12 | 13 | void setup() { 14 | 15 | // I2C init 16 | Wire.begin(); 17 | 18 | // Turn off all GPIO pins on both I2C expanders by writing all "1" 19 | Wire.beginTransmission(addr1); 20 | Wire.write(0xFF); 21 | Wire.endTransmission(); 22 | 23 | Wire.beginTransmission(addr2); 24 | Wire.write(0xFF); 25 | Wire.endTransmission(); 26 | 27 | // Assign an interrupt routine using Uno pin 2 28 | // PCF8574 /int output connects to Uno pin 2 29 | // Interrupt is triggered when a GPIO input changes from high to low 30 | pinMode(2, INPUT_PULLUP); 31 | attachInterrupt(digitalPinToInterrupt(2), ISR_PROC, FALLING); 32 | 33 | } 34 | 35 | 36 | void loop() { 37 | LED_Pattern = 0xFFFE; // Start each LED chase cycle with one LED on (set to "0") in the LSB position 38 | 39 | for (int i = 0; i < 16; i++) // Cycle through all 16 GPIO pins, shifting the "ON" LED along 40 | { 41 | // Poll I2C device 2 to check if any input has been asserted low (button press) 42 | // If any button has been pressed, overwrite the LED pattern with alternating ON/OFF status 43 | // as long as any button on device 2 is being pressed. 44 | // When the button is released, normal LED sequencing will resume as the temporary 45 | // pattern is flushed (shifted out of the display) 46 | 47 | ConfigureInputs(addr2); // Configure device 2 for input polling (device 1 is interrupt driven) 48 | int InputData2 = ReadInputs(addr2); // Read all 8 GPIO inputs on device 2 49 | if ( InputData2 != 0xFF) // If any inputs were "0", a button has been pressed 50 | { 51 | LED_Pattern = 0x7E7E; // To indicate a button was pressed, turn on LSB/MSB LED 52 | } 53 | 54 | // Send the LSB 8 bits of LED_Pattern out to device 1 55 | Wire.beginTransmission(addr1); 56 | Wire.write(lowByte(LED_Pattern)); 57 | Wire.endTransmission(); 58 | 59 | // Send the MSB 8 bits of LED_Pattern out to device 2 60 | Wire.beginTransmission(addr2); 61 | Wire.write(highByte(LED_Pattern)); 62 | Wire.endTransmission(); 63 | 64 | LED_Pattern = LED_Pattern << 1; // Shift all bits left, moving the "0" along to turn on the next LED 65 | bitSet (LED_Pattern, 0); // Set the LSB to "1" after shifting left so a "1" is piped in to keep trailing LEDs off 66 | // since shifting left will leave a "0" to the right, which will turn on an LED 67 | 68 | delay(100); // LED chase display pause 69 | 70 | // If an interrupt was flagged, force a unique pattern on the LEDs 71 | // and pause long enough to see it before resuming program 72 | // Something more useful can be done such as debouncing and 73 | // detecting which input was triggered 74 | if (ISR_FLAG) 75 | { 76 | Wire.beginTransmission(addr1); 77 | Wire.write(0x77); 78 | Wire.endTransmission(); 79 | delay(2000); 80 | ISR_FLAG = false; // Clear interrupt flag 81 | } 82 | } 83 | } 84 | 85 | 86 | // Set a flag if an interrupt is triggered 87 | void ISR_PROC() 88 | { 89 | ISR_FLAG = true; 90 | } 91 | 92 | // Configure ports for input mode by writing all "1"'s to addressed device port 93 | void ConfigureInputs(int address) 94 | { 95 | Wire.beginTransmission(address); 96 | Wire.write(0xFF); // set ports high for input mode 97 | Wire.endTransmission(); 98 | } 99 | 100 | // Read the port data on the addressed device port 101 | byte ReadInputs(int address) 102 | { 103 | Wire.beginTransmission(address); 104 | Wire.requestFrom(address, 1); 105 | int Data_In = Wire.read(); 106 | Wire.endTransmission(); 107 | return Data_In; 108 | } 109 | 110 | 111 | // END PROGRAM 112 | 113 | -------------------------------------------------------------------------------- /Uno/PCF8574/readme.md: -------------------------------------------------------------------------------- 1 | Example of using the PCF8574 8 channel GPIO I2C expander with Arduino Uno. 2 | Project: 16 LED light chaser with 8 polled switch inputs and 8 interrupt driven inputs. 3 | -------------------------------------------------------------------------------- /Uno/PCF8574_Relays/PCF8574_Relay_Control_ESP8266_Schematic.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GadgetReboot/Arduino/adf95ad05b710d7a58421f86df913644a04948d4/Uno/PCF8574_Relays/PCF8574_Relay_Control_ESP8266_Schematic.jpg -------------------------------------------------------------------------------- /Uno/PCF8574_Relays/PCF8574_Relay_Control_Uno_Schematic.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GadgetReboot/Arduino/adf95ad05b710d7a58421f86df913644a04948d4/Uno/PCF8574_Relays/PCF8574_Relay_Control_Uno_Schematic.jpg -------------------------------------------------------------------------------- /Uno/PCF8574_Relays/PCF8574_Relays.ino: -------------------------------------------------------------------------------- 1 | /************************************************************************************ 2 | 3 | Using an Arduino Uno or an ESP8266 on NodeMCU to control buttons 4 | and relays through a PCF8574 GPIO expander. 5 | 6 | Requires the PCF8574 library 7 | https://github.com/RobTillaart/Arduino/tree/master/libraries/PCF8574 8 | 9 | 10 | If using Uno, comment out #define intPin D4 11 | If using ESP8266, comment out #define intPin 2 12 | 13 | GPIO expander pinout: 0..3 = button input 0..3 14 | 4..7 = relay output 0..3 15 | Each button controls a corresponding relay 16 | eg. button 0 controls relay 0 17 | 18 | Button functions: button 0 and 1 toggle relay 0 and 1 on each press 19 | button 2 and 3 directly control relay 2 and 3 in "realtime" 20 | 21 | 22 | Gadget Reboot 23 | 24 | *************************************************************************************/ 25 | 26 | 27 | #include 28 | #include 29 | 30 | PCF8574 pcf8574(0x20); 31 | 32 | // uncomment the applicable line if using Uno or ESP8266 33 | #define intPin 2 // interrupt input Uno 34 | //#define intPin D4 // interrupt input NodeMCU ESP8266 35 | 36 | volatile bool buttonPressed = false; // button interrupt flag 37 | byte buttonReg; // button read register 38 | 39 | void setup() { 40 | 41 | // initialize PCF8574 with an interrupt pin and set all outputs to '1' (Relays off) 42 | Wire.begin(); 43 | pinMode(intPin, INPUT_PULLUP); 44 | attachInterrupt(digitalPinToInterrupt(intPin), buttonISR, FALLING); 45 | pcf8574.begin(0xFF); // turn off all Relays 46 | 47 | } 48 | 49 | void loop() { 50 | 51 | // if a button press was detected via interrupt, check if the button press 52 | // occurred on one of the "toggle" control buttons and toggle the relay if so 53 | if (buttonPressed) { 54 | delay(50); // crude debounce 55 | buttonReg = pcf8574.read8(); 56 | 57 | // toggle a relay if button pressed 58 | if (!bitRead(buttonReg, 0)) { 59 | pcf8574.toggle(4); 60 | } 61 | 62 | // toggle a relay if button pressed 63 | if (!bitRead(buttonReg, 1)) { 64 | pcf8574.toggle(5); 65 | } 66 | } 67 | 68 | // clear interrupt flag 69 | buttonPressed = false; 70 | 71 | // manually poll last two buttons and set relays to match button on/off realtime state 72 | // method 1: read all buttons and choose the desired button from the read register 73 | buttonReg = pcf8574.read8(); 74 | pcf8574.write(6, bitRead(buttonReg, 2)); 75 | 76 | // method 2: directly read just one button and directly set the target relay 77 | pcf8574.write(7, pcf8574.read(3)); 78 | 79 | } 80 | 81 | // interrupt service routine 82 | void buttonISR() { 83 | buttonPressed = true; 84 | } 85 | -------------------------------------------------------------------------------- /Uno/PCF8574_Relays/readme.md: -------------------------------------------------------------------------------- 1 | Using an Uno or ESP8266 with a PCF8574 GPIO expander to drive opto isolated relays. 2 | -------------------------------------------------------------------------------- /Uno/RotaryJoystickMame/RotaryJoystickSchematic_3pin.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GadgetReboot/Arduino/adf95ad05b710d7a58421f86df913644a04948d4/Uno/RotaryJoystickMame/RotaryJoystickSchematic_3pin.jpg -------------------------------------------------------------------------------- /Uno/RotaryJoystickMame/RotaryJoystickSchematic_4pin.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GadgetReboot/Arduino/adf95ad05b710d7a58421f86df913644a04948d4/Uno/RotaryJoystickMame/RotaryJoystickSchematic_4pin.jpg -------------------------------------------------------------------------------- /Uno/RotaryJoystickMame/Rotary_Joystick_To_MAME_3pin.ino: -------------------------------------------------------------------------------- 1 | // LS-30 Rotary Joystick to MAME Interface 2 | // Reads the 12 rotary switches and detects when the position has changed. 3 | // Generates a momentary output pulse to indicate a clockwise or 4 | // counter-clockwise movement has occurred. 5 | // 6 | // MAME is configured to take CW/CCW inputs to play arcade games that used 7 | // these joysticks with 12 inputs so this adapter is required to translate 8 | // the joystick switches into usable rotation signals for MAME. 9 | // 10 | // Target Hardware: Arduino Uno 11 | // Rotary Joystick with 12 position switch and common connection 12 | // 13 | // Connections: 14 | // Joystick Harness Pin Arduino Pin 15 | // 1, 4, 7, 10 2 16 | // 2, 5, 8, 11 3 17 | // 3, 6, 9, 12 4 18 | // 13 GND 19 | // 20 | // Outputs: 21 | // Clockwise 8 22 | // Counter-Clockwise 9 23 | // 24 | // Required libraries and board files: 25 | // Bounce2 switch debouncer https://github.com/thomasfredericks/Bounce2 26 | // 27 | // This project sketch and schematic can be found at: 28 | // https://github.com/GadgetReboot/Arduino/tree/master/Uno/RotaryJoystickMame 29 | // 30 | // Gadget Reboot 31 | // https://www.youtube.com/gadgetreboot 32 | 33 | 34 | #define DEBUG 0 35 | 36 | #include 37 | 38 | #define debounceTime 40 // switch debounce in ms 39 | #define cwOut 8 // cw output pin 40 | #define ccwOut 9 // ccw output pin 41 | #define numInputs 3 // # of inputs to read the rotary switches 42 | const uint8_t rotarySwitch[numInputs] = {2, 3, 4}; // digital inputs for rotary switches 43 | 44 | byte lastState = 0; // previous stored joystick reading 45 | byte curState = 0; // current joystick reading to evaluate against last reading 46 | bool cw = false; // detected a clockwise rotation 47 | bool ccw = false; // detected a counter-clockwise rotation 48 | bool outputOn = false; // a cw or ccw output is currently being asserted (controlled by a timer) 49 | unsigned long outputOnTime = 100; // duration to assert outputs, in mS. keyboard encoder needed a long press time 50 | unsigned long outputTimer = 0; // timer for asserting outputs for required time lapse 51 | 52 | #if Debug 53 | byte debugCount = 0; // for debug purposes, how many rotations detected since power on? 54 | #endif 55 | 56 | Bounce * joystickInputs = new Bounce[numInputs]; 57 | 58 | void setup() { 59 | 60 | #if Debug 61 | Serial.begin(9600); 62 | Serial.println("\nStart...\n"); 63 | #endif 64 | 65 | // outputs must idle high and assert active low 66 | // configure cw/ccw outputs by first setting them high, 67 | // then set them as outputs so they will be guaranteed high 68 | digitalWrite(cwOut, 1); 69 | digitalWrite(ccwOut, 1); 70 | pinMode(cwOut, OUTPUT); 71 | pinMode(ccwOut, OUTPUT); 72 | 73 | for (int i = 0; i < numInputs; i++) { 74 | joystickInputs[i].attach( rotarySwitch[i] , INPUT_PULLUP ); // setup the bounce instance for the current button 75 | joystickInputs[i].interval(debounceTime); // debounce interval in ms 76 | } 77 | 78 | // take an initial reading of the rotary switches 79 | for (int i = 0; i < numInputs; i++) { 80 | joystickInputs[i].update(); // update the switch status 81 | if (joystickInputs[i].read() == LOW) { // if a switch was grounded, update the status register 82 | bitSet(curState, i); 83 | } 84 | } 85 | 86 | lastState = curState; // make last and current readings identical to avoid a false output trigger on power up 87 | 88 | #if Debug 89 | Serial.print("Last Reading: "); 90 | Serial.println(lastState, BIN); 91 | Serial.print("Cur Reading: "); 92 | Serial.println(curState, BIN); 93 | #endif 94 | 95 | } // end setup() 96 | 97 | 98 | void loop() { 99 | 100 | readJoystick(); // read the current rotary switch states into curState register 101 | processJoystick(); // determine if a rotation has occurred and set a flag if so 102 | 103 | if (cw | ccw) { // if a rotation has been flagged, generate required output pulse 104 | generateOutput(); 105 | } 106 | 107 | // if an output is being asserted and the timer has lapsed, 108 | // stop asserting the output 109 | if ( (outputOn) && (millis() > outputTimer + outputOnTime) ) { 110 | cancelOutput(); 111 | } 112 | } // end loop() 113 | 114 | 115 | // read the joystick rotary switches into the curState register 116 | void readJoystick() { 117 | 118 | for (int i = 0; i < numInputs; i++) { 119 | joystickInputs[i].update(); // update the debouncer status 120 | if (joystickInputs[i].fell()) { // if a switch was grounded, update the status register 121 | curState = 0; // clear the register and re-build it from current switch reading 122 | bitSet(curState, i); 123 | } 124 | } 125 | } // end readJoystick() 126 | 127 | 128 | // check if rotary switches are different from last saved reading 129 | // and set the appropriate flag for the detected rotation 130 | void processJoystick() { 131 | 132 | int diff = (lastState - curState); // check for a difference in joystick readings 133 | 134 | // clockwise rotation has occurred 135 | if ( ((diff < 0) && !((lastState == B001) && (curState == B100))) | 136 | ((diff > 0) && (lastState == B100) && (curState == B001)) ) { 137 | #if Debug 138 | Serial.println("-----"); 139 | Serial.println("CW Detected - Process Joystick"); 140 | Serial.print("Last Reading: "); 141 | Serial.println(lastState, BIN); 142 | Serial.print("Cur Reading: "); 143 | Serial.println(curState, BIN); 144 | Serial.println(); 145 | #endif 146 | cw = true; 147 | } 148 | 149 | // counter-clockwise rotation has occurred 150 | if ( ((diff > 0) && !((lastState == B100) && (curState == B001))) | 151 | ((diff < 0) && (lastState == B001) && (curState == B100)) ) { 152 | #if Debug 153 | Serial.println("-----"); 154 | Serial.println("CCW Detected - Process Joystick"); 155 | Serial.print("Last Reading: "); 156 | Serial.println(lastState, BIN); 157 | Serial.print("Cur Reading: "); 158 | Serial.println(curState, BIN); 159 | Serial.println(); 160 | #endif 161 | ccw = true; 162 | } 163 | 164 | // update the last joystick reading if there's a new position 165 | if (cw | ccw) 166 | lastState = curState; 167 | 168 | } // end processJoystick() 169 | 170 | 171 | // assert the cw or ccw output signals low to indicate the direction of rotation. 172 | void generateOutput() { 173 | 174 | if (cw) { 175 | #if Debug 176 | Serial.println("Generating CW Out"); 177 | #endif 178 | digitalWrite(cwOut, 0); 179 | cw = false; 180 | } 181 | 182 | if (ccw) { 183 | #if Debug 184 | Serial.println("Generating CCW Out"); 185 | #endif 186 | digitalWrite(ccwOut, 0); 187 | ccw = false; 188 | } 189 | outputOn = true; 190 | outputTimer = millis(); // reset timer for asserted output signal 191 | } // end generateOutput() 192 | 193 | 194 | // cancel active output flag and stop asserting outputs, letting them idle high 195 | void cancelOutput() { 196 | 197 | #if Debug 198 | debugCount += 1; 199 | Serial.println("Clearing Outputs"); 200 | Serial.print("Count: "); 201 | Serial.println(debugCount); 202 | Serial.println("-----"); 203 | #endif 204 | 205 | digitalWrite(cwOut, 1); 206 | digitalWrite(ccwOut, 1); 207 | outputOn = false; 208 | } // end cancelOutput() 209 | -------------------------------------------------------------------------------- /Uno/RotaryJoystickMame/Rotary_Joystick_To_MAME_4pin.ino: -------------------------------------------------------------------------------- 1 | // LS-30 Rotary Joystick to MAME Interface 2 | // Reads the 12 rotary switches and detects when the position has changed. 3 | // Generates a momentary output pulse to indicate a clockwise or 4 | // counter-clockwise movement has occurred. 5 | // 6 | // MAME is configured to take CW/CCW inputs to play arcade games that used 7 | // these joysticks with 12 inputs so this adapter is required to translate 8 | // the joystick switches into usable rotation signals for MAME. 9 | // 10 | // Target Hardware: Arduino Uno 11 | // Rotary Joystick with 12 position switch and common connection 12 | // 13 | // Connections: 14 | // Joystick Harness Pin Arduino Pin 15 | // 1, 5, 9 2 16 | // 2, 6, 10 3 17 | // 3, 7, 11 4 18 | // 4, 8, 12 5 19 | // 13 GND 20 | // 21 | // Outputs: 22 | // Clockwise 8 23 | // Counter-Clockwise 9 24 | // 25 | // Required libraries and board files: 26 | // Bounce2 switch debouncer https://github.com/thomasfredericks/Bounce2 27 | // 28 | // Gadget Reboot 29 | // https://www.youtube.com/gadgetreboot 30 | 31 | 32 | #define DEBUG 0 33 | 34 | #include 35 | 36 | #define debounceTime 40 // switch debounce in ms 37 | #define cwOut 8 // cw output pin 38 | #define ccwOut 9 // ccw output pin 39 | #define numInputs 4 // use 4 inputs to read the rotary switches 40 | const uint8_t rotarySwitch[numInputs] = {2, 3, 4, 5}; // digital inputs for rotary switches 41 | 42 | byte lastState = 0; // previous stored joystick reading 43 | byte curState = 0; // current joystick reading to evaluate against last reading 44 | bool cw = false; // detected a clockwise rotation 45 | bool ccw = false; // detected a counter-clockwise rotation 46 | bool outputOn = false; // a cw or ccw output is currently being asserted (controlled by a timer) 47 | unsigned long outputOnTime = 100; // duration to assert outputs, in mS. keyboard encoder needed a long press time 48 | unsigned long outputTimer = 0; // timer for asserting outputs for required time lapse 49 | 50 | #if Debug 51 | byte debugCount = 0; // for debug purposes, how many rotations detected since power on? 52 | #endif 53 | 54 | Bounce * buttons = new Bounce[numInputs]; 55 | 56 | void setup() { 57 | 58 | #if Debug 59 | Serial.begin(9600); 60 | Serial.println("\nStart...\n"); 61 | #endif 62 | 63 | // outputs must idle high and assert active low 64 | // configure cw/ccw outputs by first setting them high, 65 | // then set them as outputs so they will be guaranteed high 66 | digitalWrite(cwOut, 1); 67 | digitalWrite(ccwOut, 1); 68 | pinMode(cwOut, OUTPUT); 69 | pinMode(ccwOut, OUTPUT); 70 | 71 | for (int i = 0; i < numInputs; i++) { 72 | buttons[i].attach( rotarySwitch[i] , INPUT_PULLUP ); // setup the bounce instance for the current button 73 | buttons[i].interval(debounceTime); // debounce interval in ms 74 | } 75 | 76 | // take an initial reading of the rotary switches 77 | for (int i = 0; i < numInputs; i++) { 78 | buttons[i].update(); // update the switch status 79 | if (buttons[i].read() == LOW) { // if a switch was grounded, update the status register 80 | bitSet(curState, i); 81 | } 82 | } 83 | 84 | lastState = curState; // make last and current readings identical to avoid a false output trigger on power up 85 | 86 | #if Debug 87 | Serial.print("Last Reading: "); 88 | Serial.println(lastState, BIN); 89 | Serial.print("Cur Reading: "); 90 | Serial.println(curState, BIN); 91 | #endif 92 | 93 | } // end setup() 94 | 95 | 96 | void loop() { 97 | 98 | readJoystick(); // read the current rotary switch states into curState register 99 | processJoystick(); // determine if a rotation has occurred and set a flag if so 100 | 101 | if (cw | ccw) { // if a rotation has been flagged, generate required output pulse 102 | generateOutput(); 103 | } 104 | 105 | // if an output is being asserted and the timer has lapsed, 106 | // stop asserting the output 107 | if ( (outputOn) && (millis() > outputTimer + outputOnTime) ) { 108 | cancelOutput(); 109 | } 110 | } // end loop() 111 | 112 | 113 | // read the joystick rotary switches into the curState register 114 | void readJoystick() { 115 | 116 | for (int i = 0; i < numInputs; i++) { 117 | buttons[i].update(); // update the debouncer status 118 | if (buttons[i].fell()) { // if a switch was grounded, update the status register 119 | curState = 0; // clear the register and re-build it from current switch reading 120 | bitSet(curState, i); 121 | } 122 | } 123 | } // end readJoystick() 124 | 125 | 126 | // check if rotary switches are different from last saved reading 127 | // and set the appropriate flag for the detected rotation 128 | void processJoystick() { 129 | 130 | int diff = (lastState - curState); // check for a difference in joystick readings 131 | 132 | // clockwise rotation has occurred 133 | if ( ((diff < 0) && !((lastState == B0001) && (curState == B1000))) | 134 | ((diff > 0) && (lastState == B1000) && (curState == B0001)) ) { 135 | #if Debug 136 | Serial.println("-----"); 137 | Serial.println("CW Detected - Process Joystick"); 138 | Serial.print("Last Reading: "); 139 | Serial.println(lastState, BIN); 140 | Serial.print("Cur Reading: "); 141 | Serial.println(curState, BIN); 142 | Serial.println(); 143 | #endif 144 | cw = true; 145 | } 146 | 147 | // counter-clockwise rotation has occurred 148 | if ( ((diff > 0) && !((lastState == B1000) && (curState == B0001))) | 149 | ((diff < 0) && (lastState == B0001) && (curState == B1000)) ) { 150 | #if Debug 151 | Serial.println("-----"); 152 | Serial.println("CCW Detected - Process Joystick"); 153 | Serial.print("Last Reading: "); 154 | Serial.println(lastState, BIN); 155 | Serial.print("Cur Reading: "); 156 | Serial.println(curState, BIN); 157 | Serial.println(); 158 | #endif 159 | ccw = true; 160 | } 161 | 162 | // update the last joystick reading if there's a new position 163 | if (cw | ccw) 164 | lastState = curState; 165 | 166 | } // end processJoystick() 167 | 168 | 169 | // assert the cw or ccw output signals low to indicate the direction of rotation. 170 | void generateOutput() { 171 | 172 | if (cw) { 173 | #if Debug 174 | Serial.println("Generating CW Out"); 175 | #endif 176 | digitalWrite(cwOut, 0); 177 | cw = false; 178 | } 179 | 180 | if (ccw) { 181 | #if Debug 182 | Serial.println("Generating CCW Out"); 183 | #endif 184 | digitalWrite(ccwOut, 0); 185 | ccw = false; 186 | } 187 | outputOn = true; 188 | outputTimer = millis(); // reset timer for asserted output signal 189 | } // end generateOutput() 190 | 191 | 192 | // cancel active output flag and stop asserting outputs, letting them idle high 193 | void cancelOutput() { 194 | 195 | #if Debug 196 | debugCount += 1; 197 | Serial.println("Clearing Outputs"); 198 | Serial.print("Count: "); 199 | Serial.println(debugCount); 200 | Serial.println("-----"); 201 | #endif 202 | 203 | digitalWrite(cwOut, 1); 204 | digitalWrite(ccwOut, 1); 205 | outputOn = false; 206 | } // end cancelOutput() 207 | -------------------------------------------------------------------------------- /Uno/RotaryJoystickMame/readme.txt: -------------------------------------------------------------------------------- 1 | Using Arduino Uno to read in a 12 position rotary switch arcade joystick and convert its rotations into clockwise or counter-clockwise outputs. 2 | These signals can be connected to a computer keyboard circuit to be used in MAME to play games that used these SNK LS-30 joysticks such as Ikari Warriors and Guerrilla War. 3 | -------------------------------------------------------------------------------- /Uno/SHT21_TFT_LCD/SHT21_Schematic.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GadgetReboot/Arduino/adf95ad05b710d7a58421f86df913644a04948d4/Uno/SHT21_TFT_LCD/SHT21_Schematic.jpg -------------------------------------------------------------------------------- /Uno/SHT21_TFT_LCD/readme.md: -------------------------------------------------------------------------------- 1 | Demo showing how to read in temperature/humidity data from the UART, 2 | being sent out from another device that is reading from the SHT21 sensor. 3 | 4 | Shows how to draw a thermometer graphic and analog humidity meter on the touch screen 5 | as well as use touch screen buttons to switch between degrees C and F 6 | -------------------------------------------------------------------------------- /Uno/SSD1306_Soil_Meter/Capacitive Soil Probe OLED Schematic.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GadgetReboot/Arduino/adf95ad05b710d7a58421f86df913644a04948d4/Uno/SSD1306_Soil_Meter/Capacitive Soil Probe OLED Schematic.jpg -------------------------------------------------------------------------------- /Uno/SSD1306_Soil_Meter/SSD1306_Soil_Meter.ino: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | This is an example for reading the analog sensor output of a 3 | capacitive soil moisture probe and displaying the result on a 4 | 128x64 OLED display over the I2C bus. 5 | 6 | This example requires the SSD1306 display driver by Adafruit: 7 | https://github.com/adafruit/Adafruit_SSD1306 8 | 9 | Video detailing the capacitive soil moisture measurement probe: 10 | https://youtu.be/pdGRs7GXBeE 11 | 12 | *********************************************************************/ 13 | 14 | #include 15 | #include 16 | 17 | #define OLED_RESET 4 18 | Adafruit_SSD1306 display(OLED_RESET); 19 | 20 | // make sure the SSD1306 driver is configured for 64 line height 21 | #if (SSD1306_LCDHEIGHT != 64) 22 | #error("Height incorrect, please fix Adafruit_SSD1306.h!"); 23 | #endif 24 | 25 | const int wetProbe = 300; // wet readings are around 1.5v or analog input value ~300 26 | const int dryProbe = 620; // dry readings are around 3v or analog input value ~620 27 | 28 | 29 | // Analog Sensor Input Pin 30 | int sensorInput = 0; // soil probe is on analog input 0 31 | 32 | // Variables 33 | int validSensorReading = 0; // valid sensor analog reading to record 34 | int sensorReading; // new sensor reading to evaluate and record or discard 35 | int sensorResult; // scaled sensor data [0..3] = [wet, damp, moist, dry] 36 | 37 | 38 | void setup() { 39 | 40 | Serial.begin(9600); // some debug messages will display sensor raw data 41 | 42 | display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // initialize with the I2C address of the display 43 | display.clearDisplay(); // clear the display buffer 44 | } 45 | 46 | 47 | void loop() { 48 | 49 | sensorReading = analogRead(sensorInput); 50 | if (abs(validSensorReading - sensorReading) > 10) { 51 | validSensorReading = sensorReading; 52 | } 53 | 54 | Serial.print ("Old Sensor Reading: "); 55 | Serial.println (validSensorReading); 56 | Serial.print ("New Sensor Reading: "); 57 | Serial.println (sensorReading); 58 | 59 | sensorResult = map(validSensorReading, wetProbe, dryProbe, 0, 4); // scale analog input to a smaller range for wet to dry 60 | 61 | Serial.print ("Scaled Sensor Reading 0-4: "); 62 | Serial.println (sensorResult); 63 | Serial.println (); 64 | 65 | 66 | // display the correct soil moisture level on the display 67 | // lower voltages represent more wet levels 68 | switch (sensorResult) { 69 | case 0: 70 | displayTextProbe("Wet"); 71 | break; 72 | case 1: 73 | displayTextProbe("Damp"); 74 | break; 75 | case 2: 76 | displayTextProbe("Moist"); 77 | break; 78 | case 3: 79 | displayTextProbe("Dry"); 80 | break; 81 | case 4: // same as case 3, due to how map works. 82 | displayTextProbe("Dry"); 83 | break; 84 | } 85 | delay(500); 86 | } 87 | 88 | void displayTextProbe(const char * sensorDisplay) { 89 | display.setTextSize(2); 90 | display.setTextColor(WHITE); 91 | display.setCursor(0, 0); 92 | display.clearDisplay(); 93 | display.println("Soil: "); 94 | display.println(sensorDisplay); 95 | display.display(); 96 | delay(1); 97 | } 98 | 99 | 100 | 101 | 102 | 103 | -------------------------------------------------------------------------------- /Uno/SSD1306_Soil_Meter/SSD1306_Soil_Meter_PWR_Save.ino: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | This is an example for reading the analog sensor output of a 3 | capacitive soil moisture probe and displaying the result on a 4 | 128x64 OLED display over the I2C bus. 5 | 6 | The sensor power is controlled by a P-Channel FET to only power 7 | it on when it's time to make a measurement, saving battery power. 8 | 9 | This example requires the SSD1306 display driver by Adafruit: 10 | https://github.com/adafruit/Adafruit_SSD1306 11 | 12 | *********************************************************************/ 13 | 14 | #include 15 | #include 16 | 17 | #define OLED_RESET 4 18 | Adafruit_SSD1306 display(OLED_RESET); 19 | 20 | // make sure the SSD1306 driver is configured for 64 line height 21 | #if (SSD1306_LCDHEIGHT != 64) 22 | #error("Height incorrect, please fix Adafruit_SSD1306.h!"); 23 | #endif 24 | 25 | const int wetProbe = 300; // wet readings are around 1.5v or analog input value ~300 26 | const int dryProbe = 620; // dry readings are around 3v or analog input value ~620 27 | 28 | 29 | // Analog Sensor Input Pin 30 | #define sensorInput 0 // soil probe is on analog input 0 31 | #define pwrOutputFET 2 // digital pin 2 drives the 5V power rail FET gate 32 | #define pwrOn LOW // FET is on when gate is low 33 | #define pwrOff HIGH // FET is off when gate is high 34 | 35 | // Variables 36 | int validSensorReading = 0; // valid sensor analog reading to record 37 | int sensorReading; // new sensor reading to evaluate and record or discard 38 | int sensorResult; // scaled sensor data [0..3] = [wet, damp, moist, dry] 39 | 40 | 41 | void setup() { 42 | 43 | Serial.begin(9600); // debug messages for sensor raw data 44 | 45 | pinMode(pwrOutputFET, OUTPUT); // FET gate to control sensor power 46 | digitalWrite(pwrOutputFET, pwrOff); // power up with sensor power off 47 | 48 | display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // initialize with the I2C address of the display 49 | display.clearDisplay(); // clear the display buffer 50 | } 51 | 52 | 53 | void loop() { 54 | 55 | displayTextProbe("Reading..."); // notify that sensor is being powered up and read 56 | digitalWrite(pwrOutputFET, pwrOn); // turn sensor power on 57 | delay(2000); // let power rail stabilize 58 | sensorReading = analogRead(sensorInput); // take sensor reading 59 | digitalWrite(pwrOutputFET, pwrOff); // turn sensor power off 60 | 61 | if (abs(validSensorReading - sensorReading) > 10) { 62 | validSensorReading = sensorReading; 63 | } 64 | 65 | Serial.print ("Old Sensor Reading: "); 66 | Serial.println (validSensorReading); 67 | Serial.print ("New Sensor Reading: "); 68 | Serial.println (sensorReading); 69 | 70 | sensorResult = map(validSensorReading, wetProbe, dryProbe, 0, 4); // scale analog input to a smaller range for wet to dry 71 | 72 | Serial.print ("Scaled Sensor Reading 0-4: "); 73 | Serial.println (sensorResult); 74 | Serial.println (); 75 | 76 | 77 | // display the correct soil moisture level on the display 78 | // lower voltages represent more wet levels 79 | switch (sensorResult) { 80 | case 0: 81 | displayTextProbe("Wet"); 82 | break; 83 | case 1: 84 | displayTextProbe("Damp"); 85 | break; 86 | case 2: 87 | displayTextProbe("Moist"); 88 | break; 89 | case 3: 90 | displayTextProbe("Dry"); 91 | break; 92 | case 4: // same as case 3, due to how map works. 93 | displayTextProbe("Dry"); 94 | break; 95 | } 96 | 97 | delay(3000); // display sensor reading for a short duration 98 | displayTextProbe("Idle..."); // notify that probe is powered off and system is idle 99 | 100 | delay(3000); // delay a long time before powering up sensor for another reading 101 | } 102 | 103 | void displayTextProbe(const char * sensorDisplay) { 104 | display.setTextSize(2); 105 | display.setTextColor(WHITE); 106 | display.setCursor(0, 0); 107 | display.clearDisplay(); 108 | display.println(sensorDisplay); 109 | display.display(); 110 | delay(1); 111 | } 112 | 113 | 114 | 115 | 116 | 117 | -------------------------------------------------------------------------------- /Uno/SSD1306_Soil_Meter/readme.me: -------------------------------------------------------------------------------- 1 | How to read a capacitive soil moisture sensor with Arduino and display the moisture level on a 128x64 OLED display 2 | -------------------------------------------------------------------------------- /Uno/Serial_Plotter/Serial_Plotter.ino: -------------------------------------------------------------------------------- 1 | /********************************************************************* 2 | This is an example for displaying data on the 3 | Arduino Serial Plotter. 4 | 5 | An analog signal on A0 and a DS18B20 digital temperature sensor 6 | on digital input 2 are continuously read and displayed on the 7 | Serial interface. Launch the Serial Plotter from the Tools 8 | menu in the Arduino IDE to observe the plot. 9 | 10 | Gadget Reboot 11 | 12 | *********************************************************************/ 13 | 14 | #include 15 | #include 16 | 17 | #define ONE_WIRE_BUS 2 // DS18B20 data wire is connected to input 2 18 | 19 | DeviceAddress thermometerAddress; // custom array type to hold 64 bit device address 20 | OneWire oneWire(ONE_WIRE_BUS); // create a oneWire instance to communicate with temperature IC 21 | DallasTemperature tempSensor(&oneWire); // pass the oneWire reference to Dallas Temperature 22 | 23 | 24 | void setup() { 25 | 26 | Serial.begin(9600); 27 | 28 | tempSensor.begin(); // initialize the temp sensor 29 | tempSensor.getAddress(thermometerAddress, 0); // find the address of the DS18B20 on the one wire bus 30 | tempSensor.setResolution(thermometerAddress, 11); // set the temperature resolution (9-12) 31 | } 32 | 33 | 34 | void loop() { 35 | 36 | // show temperature °C 37 | tempSensor.requestTemperatures(); // request temperature sample from sensor on the one wire bus 38 | Serial.print(tempSensor.getTempC(thermometerAddress)); // serial debug output of temperature sensor data 39 | Serial.print(" "); // multiple plot data points are separated by space, comma, or \t 40 | 41 | // show analog 0 input 42 | //Serial.print(analogRead(A0)); // read the analog input and send the data to the serial plotter 43 | //Serial.print(" "); 44 | 45 | // show analog 0 input scaled to fit other data 46 | Serial.print(analogRead(A0)/32); // read the analog input and send the data to the serial plotter 47 | Serial.print(" "); 48 | 49 | Serial.print(32); // plot straight line to set upper scaling boundary 50 | Serial.print(" "); 51 | 52 | Serial.print(0); // plot straight line to set lower scaling boundary 53 | Serial.print(" "); 54 | 55 | Serial.print(16); // plot straight line to set a visual reference line 56 | Serial.print(" "); 57 | 58 | Serial.println(); // finalize the plot for all current y-axis data points 59 | } 60 | 61 | 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /Uno/Serial_Plotter/readme.md: -------------------------------------------------------------------------------- 1 | Example ways to use the Arduino serial plotter 2 | to show data as a rolling chart instead of a list 3 | of numbers in the serial monitor. 4 | -------------------------------------------------------------------------------- /Uno/Spectrum_Analyzer/SpectrumAnalyzerSchematic.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GadgetReboot/Arduino/adf95ad05b710d7a58421f86df913644a04948d4/Uno/Spectrum_Analyzer/SpectrumAnalyzerSchematic.jpg -------------------------------------------------------------------------------- /Uno/Spectrum_Analyzer/Spectrum_Analyzer.ino: -------------------------------------------------------------------------------- 1 | /* 2 | FFT Audio Spectrum Analizer 3 | Suitable for signals up to 4.5 KHz 4 | Sampling frequency on Arduino Uno is approximately 9 KHz 5 | 6 | Adapted from learnelectronics: https://www.youtube.com/watch?v=5RmQJtE61zE 7 | Which was adapted from cbm80amiga: https://www.youtube.com/watch?v=EnvhEgjrHsw 8 | 9 | Uses the FIX_FFT library: https://www.arduinolibraries.info/libraries/fix_fft 10 | 11 | Gadget Reboot 12 | */ 13 | 14 | #include // I2C library for display 15 | #include "fix_fft.h" // fixed point Fast Fourier Transform library 16 | #include // graphics library for display 17 | #include // SSD1306 OLED display library 18 | 19 | #define OLED_RESET 4 // OLED library likes to see this but it isn't used here with I2C 20 | #define OLED_ADDR 0x3C // OLED I2C address 21 | #define audioIn A0 // audio input port 22 | 23 | Adafruit_SSD1306 display(OLED_RESET); // create instance of OLED display 24 | 25 | char re[128], im[128]; // real and imaginary FFT result arrays 26 | byte ylim = 60; // OLED y-axis drawing boundary limit 27 | 28 | void setup() { 29 | display.begin(SSD1306_SWITCHCAPVCC, OLED_ADDR); // init OLED display 30 | display.clearDisplay(); // blank the display 31 | display.setTextSize(1); // configure text properties 32 | display.setTextColor(WHITE); 33 | analogReference(DEFAULT); // use the default analog reference of 5 volts (on 5V Arduino boards) 34 | // or 3.3 volts (on 3.3V Arduino boards) 35 | }; 36 | 37 | void loop() { 38 | 39 | // The FFT real/imaginary data are stored in a char data type as a signed -128 to 127 number 40 | // This allows a waveform to swing centered around a 0 reference data point 41 | // The ADC returns data between 0-1023 so it is scaled to fit within a char by dividing by 4 and subtracting 128. 42 | // eg (0 / 4) - 128 = -128 and (1023 / 4) - 128 = 127 43 | 44 | for (byte i = 0; i < 128; i++) { // read 128 analog input samples from ADC 45 | int sample = analogRead(audioIn); 46 | re[i] = sample / 4 - 128; // scale the samples to fit within a char variable 47 | im[i] = 0; // there are no imaginary samples associated with the time domain so set to 0 48 | }; 49 | 50 | fix_fft(re, im, 7, 0); // send the samples for FFT conversion, returning the real/imaginary results in the same arrays 51 | 52 | display.clearDisplay(); // clear display 53 | display.setCursor(0, 0); // set cursor to top left corner of the display 54 | display.print("Audio Spectrum"); // print a header on the top row of the display 55 | 56 | // The data array will contain frequency bin data in locations 0..127 for samples up to the sampling frequency of approx. 9 KHz 57 | // Each frequency bin will represent a center frequency of approximately (9 KHz / 128 samples) = 70 Hz 58 | // Due to Nyquist sampling requirements, we can only consider sampled frequency data up to (sampling rate / 2) or (9 KHz / 2) = 4.5 KHz 59 | // Therefore we only acknowledge the first 64 frequency bins [0..63] = [0..4.5KHz] 60 | 61 | for (byte i = 0; i < 64; i++) { 62 | int dat = sqrt(re[i] * re[i] + im[i] * im[i]); // frequency magnitude is the square root of the sum of the squares of the real and imaginary parts of a vector 63 | display.drawLine(i * 2, ylim, i * 2, ylim - dat, WHITE); // draw bars for each frequency bin from 0 Hz to 4.5 KHz 64 | }; 65 | 66 | display.display(); // update the display 67 | }; 68 | 69 | -------------------------------------------------------------------------------- /Uno/Spectrum_Analyzer/readme.md: -------------------------------------------------------------------------------- 1 | Spectrum Analyzer using OLED display and reading an analog input, performing FFT analysis, and displaying frequency bin bars. 2 | -------------------------------------------------------------------------------- /Uno/X9C_Button_Test/X9C_Button_Test.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | This is an example for using the X9Cxxx digital potentiometers, 3 | allowing control over the wiper position from min to max, and 4 | optionally saving the wiper position so it can be recalled 5 | automatically upon next power up. 6 | 7 | Uses the Bounce2 library (installed through Arduino library manager) 8 | 9 | Requires the X9C potentiometer control library by Phil Bowles 10 | https://github.com/philbowles/Arduino-X9C 11 | 12 | Note: Changes required to the original X9C.cpp file from the above GitHub 13 | library (as of Last commit Jun 8 2017) 14 | The following 2 functions should be replaced with this code: 15 | 16 | void X9C::_deselectAndSave(){ 17 | 18 | digitalWrite(_inc,LOW); //***********GADGET REBOOT CHANGED****************** 19 | delayMicroseconds(1); //***********GADGET REBOOT CHANGED****************** 20 | digitalWrite(_inc,HIGH); //***********GADGET REBOOT CHANGED****************** 21 | delayMicroseconds(1); //***********GADGET REBOOT CHANGED****************** 22 | digitalWrite(_cs,HIGH); // unselect chip and write current value to NVRAM 23 | } 24 | 25 | void X9C::_stepPot(uint8_t amt,uint8_t dir){ 26 | uint8_t cnt=(amt > X9C_MAX) ? X9C_MAX:amt-1; //***********GADGET REBOOT CHANGED****************** 27 | digitalWrite(_ud,dir); // set direction 28 | digitalWrite(_cs,LOW); // select chip 29 | delayMicroseconds(1); 30 | while(cnt--){ 31 | digitalWrite(_inc,LOW); // falling pulse triggers wiper change (xN = cnt) 32 | delayMicroseconds(1); 33 | digitalWrite(_inc,HIGH); 34 | delayMicroseconds(1); 35 | } 36 | delayMicroseconds(100); // let new value settle; (datasheet P7 tIW) 37 | } 38 | 39 | 40 | This code is released to the public domain. 41 | Gadget Reboot 42 | 43 | *******************************************************************************/ 44 | 45 | 46 | #include // X9C pot library 47 | #include // button debounce library 48 | 49 | #define UD 10 // pot up/down mode pin 50 | #define INC 11 // pot increment pin 51 | #define CS 12 // pot chip select pin 52 | #define buttonPotMin 3 // button to set pot to min point 53 | #define buttonPotMid 4 // button to set pot to mid point 54 | #define buttonPotMax 5 // button to set pot to max point 55 | #define buttonPotUp10 6 // button to inc pot by 10 56 | #define buttonPotDn10 7 // button to dec pot by 10 57 | #define buttonPotUp1 8 // button to inc pot by 1 58 | #define buttonPotDn1 9 // button to dec pot by 1 59 | 60 | // X9C wiring: pin 3[High Terminal] -- R1 -- pin 5[Wiper] -- R2 -- pin 6[Low Terminal] 61 | 62 | // The "X9C_UP" direction refers to the amount of resistance being created between the wiper and the "High" terminal 63 | // rather than the position of the wiper itself moving up toward the high terminal 64 | // (which would reduce resistance from wiper to High). 65 | // i.e. setPot(70, false) will set the resistance between the X9C device pins 5 and 3 to 70% of maximum resistance 66 | // where R1 = 70% of max, R2 = 30% of max 67 | 68 | const int debounceInterval = 10; // debounce time (ms) for button readings 69 | 70 | X9C pot; // instantiate a pot controller 71 | Bounce buttonPotMinDB = Bounce(); // instantiate a bounce object for each button 72 | Bounce buttonPotMidDB = Bounce(); 73 | Bounce buttonPotMaxDB = Bounce(); 74 | Bounce buttonPotUp10DB = Bounce(); 75 | Bounce buttonPotDn10DB = Bounce(); 76 | Bounce buttonPotUp1DB = Bounce(); 77 | Bounce buttonPotDn1DB = Bounce(); 78 | 79 | 80 | void setup() { 81 | 82 | pot.begin(CS, INC, UD); 83 | 84 | pinMode(buttonPotMin, INPUT_PULLUP); 85 | pinMode(buttonPotMid, INPUT_PULLUP); 86 | pinMode(buttonPotMax, INPUT_PULLUP); 87 | pinMode(buttonPotUp10, INPUT_PULLUP); 88 | pinMode(buttonPotDn10, INPUT_PULLUP); 89 | pinMode(buttonPotUp1, INPUT_PULLUP); 90 | pinMode(buttonPotDn1, INPUT_PULLUP); 91 | 92 | // attach buttons to debouncers 93 | buttonPotMinDB.attach(buttonPotMin); 94 | buttonPotMinDB.interval(debounceInterval); // interval in ms 95 | 96 | buttonPotMidDB.attach(buttonPotMid); 97 | buttonPotMidDB.interval(debounceInterval); // interval in ms 98 | 99 | buttonPotMaxDB.attach(buttonPotMax); 100 | buttonPotMaxDB.interval(debounceInterval); // interval in ms 101 | 102 | buttonPotUp10DB.attach(buttonPotUp10); 103 | buttonPotUp10DB.interval(debounceInterval); // interval in ms 104 | 105 | buttonPotDn10DB.attach(buttonPotDn10); 106 | buttonPotDn10DB.interval(debounceInterval); // interval in ms 107 | 108 | buttonPotUp1DB.attach(buttonPotUp1); 109 | buttonPotUp1DB.interval(debounceInterval); // interval in ms 110 | 111 | buttonPotDn1DB.attach(buttonPotDn1); 112 | buttonPotDn1DB.interval(debounceInterval); // interval in ms 113 | 114 | } 115 | 116 | void loop() { 117 | 118 | // update the Bounce instances 119 | buttonPotMinDB.update(); 120 | buttonPotMidDB.update(); 121 | buttonPotMaxDB.update(); 122 | buttonPotUp10DB.update(); 123 | buttonPotDn10DB.update(); 124 | buttonPotUp1DB.update(); 125 | buttonPotDn1DB.update(); 126 | 127 | // change potentiometer setting if required based on button presses, 128 | // storing the setting in the chip if "true" is passed to the pot controller 129 | 130 | if ( buttonPotMinDB.fell()) { 131 | pot.setPotMin(false); // set pot wiper to 0 resistance (pot will have wiper resistance per datasheet) 132 | } 133 | 134 | if ( buttonPotMidDB.fell()) { 135 | pot.setPot(49, false); // set pot wiper to about half way (between 0 and 99) 136 | } 137 | 138 | if ( buttonPotMaxDB.fell()) { 139 | pot.setPotMax(false); // set pot wiper to full resistance 140 | } 141 | 142 | if ( buttonPotUp10DB.fell()) { 143 | pot.trimPot(10, X9C_UP, true); // move pot wiper 10 positions up ***AND STORE SETTING IN X9C CHIP*** 144 | } 145 | 146 | if ( buttonPotDn10DB.fell()) { 147 | pot.trimPot(10, X9C_DOWN, false); // move pot wiper 10 positions down 148 | } 149 | 150 | if ( buttonPotUp1DB.fell()) { 151 | pot.trimPot(1, X9C_UP, false); // move pot wiper 1 position up 152 | } 153 | 154 | if ( buttonPotDn1DB.fell()) { 155 | pot.trimPot(1, X9C_DOWN, false); // move pot wiper 1 position down 156 | } 157 | 158 | } 159 | -------------------------------------------------------------------------------- /Uno/X9C_Button_Test/readme.md: -------------------------------------------------------------------------------- 1 | Testing a library for the X9C Intersil digital potentiometer from https://github.com/philbowles/Arduino-X9C 2 | 3 | X9C Datasheet: https://www.intersil.com/content/dam/Intersil/documents/x9c1/x9c102-103-104-503.pdf 4 | 5 | This test sketch uses push buttons to test the functions, allowing control of the potentiometer to 6 | move the wiper up/down by one position, ten positions, or set directly to min/mid/max levels. 7 | 8 | A save function is added to the ten position up button to test that the pot can store the wiper position 9 | when requested, allowing that wiper setting to be restored upon power on. 10 | 11 | Note that in order to get the sketch operating as expected, two functions need to be modified from the original library mentioned above. These changes are noted in the comments at the top of the sketch file X9C_Button_Test.ino 12 | 13 | X9C_Button_Test.ino is the main test sketch 14 | 15 | X9C_555_Osc_Control.ino is a modification to turn the buttons into sound effect generators when the X9C is used to replace a frequency control pot of a 555 oscillator. 16 | -------------------------------------------------------------------------------- /Uno/X9C_OpAmp_Gain_Control/OpAmp_Gain_Schematic.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GadgetReboot/Arduino/adf95ad05b710d7a58421f86df913644a04948d4/Uno/X9C_OpAmp_Gain_Control/OpAmp_Gain_Schematic.jpg -------------------------------------------------------------------------------- /Uno/X9C_OpAmp_Gain_Control/X9C_OpAmp_Gain_Control.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | This is an example for using the X9Cxxx digital potentiometers 3 | in the feedback loop of an op amp to control the gain digitally. 4 | 5 | Uses the Bounce2 library for push button debouncing 6 | 7 | Requires the X9C potentiometer control library by Phil Bowles 8 | https://github.com/philbowles/Arduino-X9C 9 | 10 | Note: Changes required to the original X9C.cpp file from GitHub 11 | (as of Last commit Jun 8 2017) 12 | The following 2 functions should be replaced with this code: 13 | 14 | void X9C::_deselectAndSave(){ 15 | 16 | digitalWrite(_inc,LOW); //***********GADGET REBOOT CHANGED****************** 17 | delayMicroseconds(1); //***********GADGET REBOOT CHANGED****************** 18 | digitalWrite(_inc,HIGH); //***********GADGET REBOOT CHANGED****************** 19 | delayMicroseconds(1); //***********GADGET REBOOT CHANGED****************** 20 | digitalWrite(_cs,HIGH); // unselect chip and write current value to NVRAM 21 | } 22 | 23 | void X9C::_stepPot(uint8_t amt,uint8_t dir){ 24 | uint8_t cnt=(amt > X9C_MAX) ? X9C_MAX:amt-1; //***********GADGET REBOOT CHANGED****************** 25 | digitalWrite(_ud,dir); // set direction 26 | digitalWrite(_cs,LOW); // select chip 27 | delayMicroseconds(1); 28 | while(cnt--){ 29 | digitalWrite(_inc,LOW); // falling pulse triggers wiper change (xN = cnt) 30 | delayMicroseconds(1); 31 | digitalWrite(_inc,HIGH); 32 | delayMicroseconds(1); 33 | } 34 | delayMicroseconds(100); // let new value settle; (datasheet P7 tIW) 35 | } 36 | 37 | 38 | This code is released to the public domain. 39 | Gadget Reboot 40 | 41 | *******************************************************************************/ 42 | 43 | 44 | #include // X9C pot library 45 | #include // button debounce library 46 | 47 | #define UD 4 // pot up/down mode pin 48 | #define INC 3 // pot increment pin 49 | #define CS 2 // pot chip select pin 50 | 51 | #define signalIn A0 // op amp output pin to read in 52 | #define debugIn A1 // analog test input to compare op amp pre/post gain 53 | 54 | #define buttonPotUp5 5 // button to inc pot by 10 55 | #define buttonPotDn5 6 // button to dec pot by 10 56 | #define buttonAutoScale 7 // button to allow serial plotter auto-scaling or to use a fixed scale 57 | 58 | 59 | // X9C wiring: pin 3[High Terminal] -- R1 -- pin 5[Wiper] -- R2 -- pin 6[Low Terminal] 60 | 61 | // The "X9C_UP" direction refers to the amount of resistance being created between the wiper and the "High" terminal 62 | // rather than the position of the wiper itself moving up toward the high terminal 63 | // (which would reduce resistance from wiper to High). 64 | // i.e. setPot(70, false) will set the resistance between the X9C device pins 5 and 3 to 70% of maximum resistance 65 | // where R1 = 70% of max, R2 = 30% of max 66 | 67 | const int debounceInterval = 10; // debounce time (ms) for button readings 68 | bool autoScale = true; // toggle whether to allow serial plotter to autoscale or stay fixed 69 | 70 | X9C pot; // instantiate a pot controller 71 | Bounce buttonPotUp5DB = Bounce(); // instantiate a bounce object for each button 72 | Bounce buttonPotDn5DB = Bounce(); 73 | Bounce buttonAutoScaleDB = Bounce(); 74 | 75 | 76 | 77 | void setup() { 78 | 79 | Serial.begin(9600); 80 | 81 | pot.begin(CS, INC, UD); 82 | pot.setPotMin(false); // set pot Vw to Vh = 0% for minimum op amp gain to start (avoid saturation) 83 | 84 | pinMode(buttonPotUp5, INPUT_PULLUP); 85 | pinMode(buttonPotDn5, INPUT_PULLUP); 86 | pinMode(buttonAutoScale, INPUT_PULLUP); 87 | 88 | 89 | // attach buttons to debouncers 90 | buttonPotUp5DB.attach(buttonPotUp5); 91 | buttonPotUp5DB.interval(debounceInterval); // interval in ms 92 | 93 | buttonPotDn5DB.attach(buttonPotDn5); 94 | buttonPotDn5DB.interval(debounceInterval); // interval in ms 95 | 96 | buttonAutoScaleDB.attach(buttonAutoScale); 97 | buttonAutoScaleDB.interval(debounceInterval); // interval in ms 98 | 99 | } 100 | 101 | void loop() { 102 | 103 | // update the Bounce instances 104 | buttonPotUp5DB.update(); 105 | buttonPotDn5DB.update(); 106 | buttonAutoScaleDB.update(); 107 | 108 | // change potentiometer setting if required based on button presses, 109 | // storing the setting in the chip if "true" is passed to the pot controller 110 | 111 | if ( buttonPotUp5DB.fell()) { 112 | pot.trimPot(5, X9C_UP, false); // move pot wiper 5 positions up 113 | } 114 | 115 | if ( buttonPotDn5DB.fell()) { 116 | pot.trimPot(5, X9C_DOWN, false); // move pot wiper 5 positions down 117 | } 118 | 119 | /* 120 | This "feature" didn't work in the serial monitor on my system so I disabled it. 121 | A ghost plot was sticking in the background of the live data on the serial plotter 122 | so I assume it's a bug with the plotter (??) so I just leave the entire program 123 | fixed to allow autoscaling or keep it fixed the whole time. 124 | 125 | if ( buttonAutoScaleDB.fell()) { 126 | autoScale = !autoScale; // toggle auto scaling of serial plotter 127 | } 128 | */ 129 | if (!autoScale) { // plot upper and lower fixed lines if not autoscaling plotter 130 | 131 | Serial.print(880); 132 | Serial.print(" "); 133 | 134 | Serial.print(0); 135 | Serial.print(" "); 136 | } 137 | 138 | Serial.print(analogRead(signalIn)); // plot analog signal from op amp with gain 139 | Serial.print(" "); 140 | 141 | Serial.print(analogRead(debugIn)); // plot signal generator analog in 142 | Serial.print(" "); 143 | 144 | Serial.println(); 145 | 146 | } 147 | -------------------------------------------------------------------------------- /Uno/X9C_OpAmp_Gain_Control/readme.mc: -------------------------------------------------------------------------------- 1 | Using an X9C digital potentiometer to allow Arduino to 2 | control the gain setting of an op amp. 3 | -------------------------------------------------------------------------------- /Uno/readme.md: -------------------------------------------------------------------------------- 1 | # Arduino Uno Projects 2 | 3 | Arduino projects will be housed here. 4 | --------------------------------------------------------------------------------