├── .gitattributes ├── 9781484263358.jpg ├── Chapter 1 ├── Listing1-1 │ └── Listing1-1.ino ├── Listing1-2 │ └── Listing1-2.ino ├── Listing1-3_NEW │ └── Listing1-3_NEW.ino └── Listing1-4 │ └── Listing1-4.ino ├── Chapter 10 ├── Control-and-feedback.aia ├── Listing10-1 │ └── Listing10-1.ino ├── Servo-robot-control.aia ├── Speech-recognition.aia ├── Table10-2_left-side │ └── Table10-2_left-side.ino └── Table10-2_right-side │ └── Table10-2_right-side.ino ├── Chapter 11 ├── Database.aia └── Location-database.aia ├── Chapter 12 ├── GPS-tracking.aia ├── Listing12-1 │ └── Listing12-1.ino ├── Listing12-2 │ └── Listing12-2.ino ├── Listing12-3 │ └── Listing12-3.ino ├── Listing12-4 │ └── Listing12-4.ino ├── Listing12-5 │ └── Listing12-5.ino ├── Listing12-6 │ └── Listing12-6.ino ├── Listing12-7 │ └── Listing12-7.ino └── Listing12-8 │ └── Listing12-8.ino ├── Chapter 13 ├── app-to-receive.aia ├── app-to-transmit.aia └── receive-and-transmit.aia ├── Chapter 14 ├── Listing14-1 │ └── Listing14-1.ino ├── Listing14-10 │ └── Listing14-10.ino ├── Listing14-11 │ └── Listing14-11.ino ├── Listing14-12 │ └── Listing14-12.ino ├── Listing14-13 │ └── Listing14-13.ino ├── Listing14-2 │ └── Listing14-2.ino ├── Listing14-3 │ └── Listing14-3.ino ├── Listing14-4 │ └── Listing14-4.ino ├── Listing14-5 │ └── Listing14-5.ino ├── Listing14-6 │ └── Listing14-6.ino ├── Listing14-7 │ └── Listing14-7.ino ├── Listing14-8 │ └── Listing14-8.ino └── Listing14-9 │ └── Listing14-9.ino ├── Chapter 15 ├── Listing15-1 │ └── Listing15-1.ino ├── Listing15-2 │ └── Listing15-2.ino ├── Listing15-3 │ └── Listing15-3.ino ├── Listing15-4 │ └── Listing15-4.ino ├── Listing15-5 │ └── Listing15-5.ino ├── Listing15-6 │ └── Listing15-6.ino └── Listing15-7 │ └── Listing15-7.ino ├── Chapter 16 ├── Listing16-1 │ └── Listing16-1.ino ├── Listing16-2 │ └── Listing16-2.ino ├── Listing16-3 │ └── Listing16-3.ino ├── Listing16-4 │ └── Listing16-4.ino ├── Listing16-5 │ └── Listing16-5.ino ├── Listing16-6 │ └── Listing16-6.ino ├── Listing16-7 │ └── Listing16-7.ino ├── Table16-1_left-side │ └── Table16-1_left-side.ino └── Table16-1_right-side │ └── Table16-1_right-side.ino ├── Chapter 18 ├── Listing18-1 │ └── Listing18-1.ino ├── Listing18-2 │ └── Listing18-2.ino ├── Listing18-3 │ └── Listing18-3.ino ├── Listing18-4 │ └── Listing18-4.ino ├── Listing18-5 │ └── Listing18-5.ino ├── Listing18-6 │ └── Listing18-6.ino ├── Listing18-7 │ └── Listing18-7.ino ├── Listing18-8 │ └── Listing18-8.ino └── Listing18-9 │ └── Listing18-9.ino ├── Chapter 19 ├── Listing19-1 │ └── Listing19-1.ino ├── Listing19-2 │ └── Listing19-2.ino ├── Listing19-3 │ └── Listing19-3.ino ├── Listing19-4 │ └── Listing19-4.ino └── Listing19-5 │ └── Listing19-5.ino ├── Chapter 2 ├── Listing2-1 │ └── Listing2-1.ino ├── Listing2-2 │ └── Listing2-2.ino ├── Listing2-3 │ └── Listing2-3.ino ├── Listing2-4 │ └── Listing2-4.ino ├── Listing2-5 │ └── Listing2-5.ino ├── Listing2-6 │ └── Listing2-6.ino └── Listing2-7 │ └── Listing2-7.ino ├── Chapter 20 ├── Listing20-1 │ └── Listing20-1.ino ├── Listing20-2 │ └── Listing20-2.ino ├── Listing20-3 │ └── Listing20-3.ino ├── Listing20-4 │ └── Listing20-4.ino ├── Listing20-5 │ └── Listing20-5.ino └── Listing20-6 │ └── Listing20-6.ino ├── Chapter 21 ├── Listing21-1 │ └── Listing21-1.ino ├── Listing21-2 │ └── Listing21-2.ino ├── Listing21-3 │ └── Listing21-3.ino ├── Listing21-4 │ └── Listing21-4.ino ├── Listing21-5_NEW │ └── Listing21-5_NEW.ino └── Listing21-6 │ └── Listing21-6.ino ├── Chapter 22 ├── Listing22-1 │ └── Listing22-1.ino ├── Listing22-10 │ └── Listing22-10.ino ├── Listing22-11 │ └── Listing22-11.ino ├── Listing22-12 │ └── Listing22-12.ino ├── Listing22-2 │ └── Listing22-2.ino ├── Listing22-3 │ └── Listing22-3.ino ├── Listing22-4 │ └── Listing22-4.ino ├── Listing22-5 │ └── Listing22-5.ino ├── Listing22-6 │ └── Listing22-6.ino ├── Listing22-7 │ └── Listing22-7.ino ├── Listing22-8 │ └── Listing22-8.ino ├── Listing22-9 │ └── Listing22-9.ino ├── Table_22-1_left-side │ └── Table_22-1_left-side.ino └── Table_22-1_right-side │ └── Table_22-1_right-side.ino ├── Chapter 3 ├── Listing3-1 │ └── Listing3-1.ino ├── Listing3-2 │ └── Listing3-2.ino ├── Listing3-3 │ └── Listing3-3.ino ├── Listing3-4 │ └── Listing3-4.ino ├── Listing3-5 │ └── Listing3-5.ino ├── Listing3-6 │ └── Listing3-6.ino ├── Listing3-7 │ └── Listing3-7.ino ├── Listing3-8 │ └── Listing3-8.ino └── Listing3-9 │ └── Listing3-9.ino ├── Chapter 4 ├── Listing4-1 │ └── Listing4-1.ino ├── Listing4-2 │ └── Listing4-2.ino ├── Listing4-3 │ └── Listing4-3.ino ├── Listing4-4 │ └── Listing4-4.ino └── Listing4-5 │ └── Listing4-5.ino ├── Chapter 5 ├── Listing5-1 │ └── Listing5-1.ino ├── Listing5-2 │ └── Listing5-2.ino ├── Listing5-3 │ └── Listing5-3.ino ├── Listing5-3_NEW │ └── Listing5-3_NEW.ino ├── Listing5-4 │ └── Listing5-4.ino ├── Listing5-5 │ └── Listing5-5.ino ├── Listing5-6 │ └── Listing5-6.ino ├── Listing5-7 │ └── Listing5-7.ino └── Listing5-8 │ └── Listing5-8.ino ├── Chapter 7 ├── Listing7-1 │ ├── Listing7-1.ino │ └── buildpage.h ├── Listing7-2 │ └── Listing7-2.ino ├── Listing7-3 │ └── Listing7-3.ino ├── Listing7-4 │ └── Listing7-4.ino ├── Listing7-5 │ └── Listing7-5.ino ├── Listing7-6 │ └── Listing7-6.ino └── Listing7-7 │ └── Listing7-7.ino ├── Chapter 8 ├── Listing8-1 │ └── Listing8-1.ino ├── Listing8-10 │ └── Listing8-10.ino ├── Listing8-2 │ └── Listing8-2.ino ├── Listing8-3 │ └── Listing8-3.ino ├── Listing8-4 │ └── Listing8-4.ino ├── Listing8-5 │ └── Listing8-5.ino ├── Listing8-6 │ └── Listing8-6.ino ├── Listing8-7 │ └── Listing8-7.ino ├── Listing8-8 │ └── Listing8-8.ino └── Listing8-9 │ └── Listing8-9.ino ├── Chapter 8_NEW ├── Listing8-8_NEW │ └── Listing8-8_NEW.ino ├── Listing8-9_NEW │ └── Listing8-9_NEW.ino └── NEW Chapter 8 Updating a webpage.pdf ├── Chapter 9 ├── Listing9-1 │ └── Listing9-1.ino ├── Listing9-2 │ └── Listing9-2.ino ├── Listing9-3 │ └── Listing9-3.ino ├── Listing9-4 │ └── Listing9-4.ino ├── Listing9-5 │ └── Listing9-5.ino ├── Listing9-6 │ └── Listing9-6.ino └── Listing9-7 │ └── Listing9-7.ino ├── Contributing.md ├── LICENSE.txt ├── README.md └── Updates and corrections Oct 2023 └── Updates and corrections Oct 2023.pdf /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /9781484263358.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/ESP8266-and-ESP32/3f223c897ff3952af75b4a12e4430d87d1927590/9781484263358.jpg -------------------------------------------------------------------------------- /Chapter 1/Listing1-2/Listing1-2.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: ESP32 vs1053_ext library functions 3 | * Description: Demonstrate output of ESP32 vs1053_ext library functions 4 | * Created on: October 2020 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 1 - Internet radio 8 | ******************************************************************************/ 9 | 10 | #include // include ESP32 VS1053_ext lib 11 | #include // include Wi-Fi library 12 | int CS = 0; 13 | int DCS = 2; // define VS1053 decoder pins 14 | int DREQ = 4; 15 | VS1053 decoder(CS, DCS, DREQ); // associate decoder with VS1053 16 | char ssid[] = "xxxx"; // change xxxx to Wi-Fi ssid 17 | char password[] = "xxxx"; // change xxxx to Wi-Fi password 18 | int volume = 10; // volume level 19 | 20 | void setup() 21 | { 22 | Serial.begin(115200); // define Serial Monitor baud rate 23 | SPI.begin(); // initialise SPI bus 24 | WiFi.begin(ssid, password); // initialise Wi-Fi 25 | while (WiFi.status() != WL_CONNECTED) delay(500); 26 | decoder.begin(); // initialise VS0153 decoder 27 | decoder.setVolume(volume); // set decoder volume level 28 | decoder.connecttohost("media-ice.musicradio.com:80/ClassicFMMP3"); 29 | } 30 | 31 | void loop() 32 | { 33 | decoder.loop(); 34 | } 35 | void vs1053_showstation(const char * info) 36 | { // display radio station name 37 | Serial.print("Station: "); 38 | Serial.println(info); 39 | } 40 | void vs1053_bitrate(const char * info) 41 | { // display streaming bit rate 42 | Serial.print("Bit rate: "); 43 | Serial.println(String(info)+"kBit/s"); 44 | } 45 | void vs1053_icyurl(const char * info) 46 | { // display radio station URL 47 | Serial.print("Homepage: "); 48 | Serial.println(info); 49 | } 50 | void vs1053_showstreamtitle(const char * info) 51 | { // title of streamed track 52 | Serial.print("Stream title: "); 53 | Serial.println(info); 54 | } 55 | -------------------------------------------------------------------------------- /Chapter 1/Listing1-4/Listing1-4.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: Minimal internet radio 3 | * Description: Internet radio with ESP32 with only 21 lines of code 4 | * Created on: October 2020 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 1 - Internet radio 8 | ******************************************************************************/ 9 | 10 | #include // include ESP32 VS1053_ext 11 | #include // and WiFi libraries 12 | int CS = 0; 13 | int DCS = 2; // define VS1053 decoder pins 14 | int DREQ = 4; 15 | VS1053 decoder(CS, DCS, DREQ); // associate decoder with VS1053 16 | char ssid[] = "xxxx"; // change xxxx to Wi-Fi ssid 17 | char password[] = "xxxx"; // change xxxx to Wi-Fi password 18 | 19 | void setup() 20 | { 21 | SPI.begin(); // initialise SPI bus 22 | WiFi.begin(ssid, password); // initialise Wi-Fi 23 | while (WiFi.status() != WL_CONNECTED) delay(500); 24 | decoder.begin(); // initialise VS0153 decoder 25 | decoder.setVolume(10); // pre-set decoder volume level 26 | decoder.connecttohost("media-ice.musicradio.com:80/ClassicFMMP3"); 27 | } // connect to pre-set radio station server 28 | 29 | void loop() 30 | { 31 | decoder.loop(); 32 | } 33 | -------------------------------------------------------------------------------- /Chapter 10/Control-and-feedback.aia: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/ESP8266-and-ESP32/3f223c897ff3952af75b4a12e4430d87d1927590/Chapter 10/Control-and-feedback.aia -------------------------------------------------------------------------------- /Chapter 10/Servo-robot-control.aia: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/ESP8266-and-ESP32/3f223c897ff3952af75b4a12e4430d87d1927590/Chapter 10/Servo-robot-control.aia -------------------------------------------------------------------------------- /Chapter 10/Speech-recognition.aia: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/ESP8266-and-ESP32/3f223c897ff3952af75b4a12e4430d87d1927590/Chapter 10/Speech-recognition.aia -------------------------------------------------------------------------------- /Chapter 10/Table10-2_left-side/Table10-2_left-side.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: Bluetooth and LED control sketch for ESP8266 microcontroller 3 | * Description: Table 10-2 left side 4 | * Created on: October 2020 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 10 - Build an app 8 | ******************************************************************************/ 9 | 10 | int LEDpin = D4; 11 | int LDRpin = A0; 12 | int bright, LDR; 13 | int LEDstate = 0; 14 | String str; 15 | unsigned int lastTime = 0; 16 | 17 | void setup() 18 | { 19 | Serial.begin(9600); 20 | pinMode(LEDpin, OUTPUT); 21 | digitalWrite(LEDpin, LEDstate); 22 | } 23 | 24 | void loop() 25 | { 26 | if(Serial.available()>0) 27 | { 28 | str = Serial.readString(); 29 | if(str == "C") 30 | { 31 | LEDstate = 1- LEDstate; 32 | if(LEDstate == 1) Serial.print("H"); 33 | else Serial.print("L"); 34 | digitalWrite(LEDpin, LEDstate); 35 | delay(20); 36 | } 37 | else if(LEDstate == 1) 38 | { 39 | bright = str.toInt(); 40 | analogWrite(LEDpin, bright); 41 | } 42 | } 43 | if(millis()-lastTime > 2000) 44 | { 45 | lastTime = millis(); 46 | LDR = analogRead(LDRpin); 47 | Serial.println(LDR); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /Chapter 10/Table10-2_right-side/Table10-2_right-side.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: Bluetooth and LED control sketch for ESP32 microcontroller 3 | * Description: Table 10-2 right side 4 | * Created on: October 2020 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 10 - Build an app 8 | ******************************************************************************/ 9 | 10 | #include 11 | BluetoothSerial SerialBT; 12 | int LEDpin = 27; 13 | int LDRpin = 33; 14 | int bright, LDR; 15 | int LEDstate = 0; 16 | int channel = 0; 17 | char c; 18 | String str; 19 | unsigned int lastTime = 0; 20 | 21 | void setup() 22 | { 23 | SerialBT.begin("ESP32 Bluetooth"); 24 | pinMode(LEDpin, OUTPUT); 25 | ledcAttachPin(LEDpin, channel); 26 | ledcSetup(channel, 1000, 8); 27 | ledcWrite(channel, LEDstate); 28 | } 29 | 30 | void loop() 31 | { 32 | if(SerialBT.available()>0) 33 | { 34 | str = ""; 35 | while(SerialBT.available()>0) 36 | { 37 | c = SerialBT.read(); 38 | str = str + String(c); 39 | } 40 | if(str == "C" ) 41 | { 42 | LEDstate = 1 - LEDstate; 43 | if(LEDstate == 1) SerialBT.print("H"); 44 | else SerialBT.print("L"); 45 | ledcWrite(channel, LEDstate*255); 46 | delay(20); 47 | } 48 | else if(LEDstate == 1) 49 | { 50 | bright = str.toInt(); 51 | ledcWrite(channel, bright); 52 | } 53 | } 54 | if(millis()-lastTime > 2000) 55 | { 56 | lastTime = millis(); 57 | LDR = analogRead(LDRpin); 58 | SerialBT.println(LDR); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /Chapter 11/Database.aia: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/ESP8266-and-ESP32/3f223c897ff3952af75b4a12e4430d87d1927590/Chapter 11/Database.aia -------------------------------------------------------------------------------- /Chapter 11/Location-database.aia: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/ESP8266-and-ESP32/3f223c897ff3952af75b4a12e4430d87d1927590/Chapter 11/Location-database.aia -------------------------------------------------------------------------------- /Chapter 12/GPS-tracking.aia: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/ESP8266-and-ESP32/3f223c897ff3952af75b4a12e4430d87d1927590/Chapter 12/GPS-tracking.aia -------------------------------------------------------------------------------- /Chapter 12/Listing12-1/Listing12-1.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: nRF24L01 transmit signal with position data for ESP8266 board 3 | * Description: transmit GPS latitude and longitude values to receiving nRF24L01 4 | * Created on: October 2020 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 12 - GPS tracking app with Google Maps 8 | ******************************************************************************/ 9 | 10 | #include // include SoftwareSerial library 11 | SoftwareSerial SoftSer(D4, D0); // associate SoftSer with SoftwareSerial 12 | #include // include NeoGPS library 13 | NMEAGPS nmea; // associate nmea and gps 14 | gps_fix gps; // with NMEAGPS library 15 | float GPSlat, GPSlong; // real numbers for GPS location 16 | int GPSsend = 0; // GPS send counter 17 | #include // include SPI library 18 | #include // include RF24 library 19 | RF24 radio(D3, D8); // associate radio with RF24 library 20 | byte addresses[ ][6] = {"12"}; // data pipe address 21 | typedef struct // define data structure to include 22 | { 23 | char GPSlat[10]; // character arrays for 24 | char GPSlong[10]; // GPS latitude and longitude 25 | } dataStruct; 26 | dataStruct data; // name the data structure as data 27 | int interval = 2; // interval (s) between GPS transmissions 28 | 29 | void setup() 30 | { // Serial connection to GPS module 31 | SoftSer.begin(9600); // SoftwareSerial baud rate 32 | delay(500); 33 | radio.begin(); // start radio 34 | radio.setChannel(50); // set channel number, 35 | radio.setDataRate(RF24_2MBPS); // baud rate 36 | radio.setPALevel(RF24_PA_HIGH); // and power amplifier 37 | radio.setAutoAck(true); // set auto-acknowledge (default) 38 | radio.openWritingPipe(addresses[0]); // initiate data transmit pipe 39 | radio.stopListening(); // nRF24L01 as transmitter 40 | } 41 | 42 | void loop() 43 | { 44 | while(nmea.available(SoftSer)>0) // GPS data available 45 | { 46 | gps = nmea.read(); // latest satellite message 47 | if(gps.valid.location) // validated GPS location 48 | { 49 | GPSlat = gps.latitude(); 50 | GPSlong = gps.longitude(); 51 | GPSsend++; // increment GPS send counter 52 | } 53 | if(GPSsend > interval) // transmit every (interval+1)s 54 | { // convert number to string and then to character array 55 | String(GPSlat,6).toCharArray(data.GPSlat,10); 56 | String(GPSlong,6).toCharArray(data.GPSlong,10); 57 | radio.write(&data, sizeof(data)); // transmit signal as data structure 58 | GPSsend = 0; // reset GPS send counter 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /Chapter 12/Listing12-2/Listing12-2.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: nRF24L01 receive signal transmitted with Bluetooth 3 | * Description: transmit the received GPS latitude and longitude values 4 | * Created on: October 2020 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 12 - GPS tracking app with Google Maps 8 | ******************************************************************************/ 9 | 10 | #include // include Bluetooth library 11 | BluetoothSerial SerialBT; // associate SerialBT with library 12 | #include // include SPI library 13 | #include // include RF24 library 14 | RF24 radio(2, 4); // associate radio with RF24 lib 15 | byte addresses[ ][6] = {"12"}; // data pipe address 16 | typedef struct // define data structure to include 17 | { 18 | char GPSlat[10]; // character arrays for 19 | char GPSlong[10]; // GPS latitude and longitude 20 | } dataStruct; 21 | dataStruct data; // name the data structure as data 22 | int count = 0; // received message counter 23 | int textLen; 24 | String text; 25 | char c; 26 | 27 | void setup() 28 | { 29 | radio.begin(); // start radio 30 | radio.setChannel(50); // set channel number 31 | radio.setDataRate(RF24_2MBPS); // baud rate 32 | radio.setPALevel(RF24_PA_HIGH); // and power amplifier 33 | radio.setAutoAck(true); // set auto-acknowledge (default) 34 | radio.openReadingPipe(0, addresses[0]); // initiate data receive pipe 35 | radio.startListening(); // nRF24L01 module as receiver 36 | SerialBT.begin("ESP32 Bluetooth"); // identify Bluetooth 37 | } 38 | 39 | void loop() 40 | { 41 | if(radio.available()) // if signal received 42 | { 43 | radio.read(&data, sizeof(data)); // received signal to data structure 44 | count++; // increment counter 45 | text = String(count) + "," + String(data.GPSlat) + "," + 46 | String(data.GPSlong) + ","; // build string of position data 47 | textLen = text.length(); 48 | for (int i=0; i 12 | ESP8266 13 | 14 | 15 | 16 |

GPS

17 |

Latitude: 0

18 |

Longitude: 0

19 |

Altitude: 0 m

20 |

Speed: 0 kph

21 |

Counter: 0

22 | 23 | 58 | 59 | )"; 60 | -------------------------------------------------------------------------------- /Chapter 12/Listing12-6/Listing12-6.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: Channel scanning 3 | * Description: determine activity on each scanned channel 4 | * Created on: October 2020 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 12 - GPS tracking app with Google Maps 8 | ******************************************************************************/ 9 | 10 | #include // include SPI library 11 | #include // include RF24 library 12 | RF24 radio(D3, D8); // associate radio with library 13 | const int nChan = 126; // 126 channels available 14 | int chan[nChan]; // store counts per channel 15 | int nScan = 100; // number of scans per channel 16 | int scan; 17 | 18 | void setup() 19 | { 20 | Serial.begin(115200); // define Serial Monitor baud rate 21 | radio.begin(); // start radio 22 | } 23 | 24 | void loop() 25 | { 26 | for (int i=0;i0) chan[i]=chan[i]+1; // a carrier on the channel 36 | } 37 | delay(1); // avoid watchdog reset 38 | } 39 | for (int i=0; i // include SPI library 11 | #include // include RF24 library 12 | RF24 radio(D3, D8); // associate radio with library 13 | byte addresses[ ][6] = {"12"}; // data pipe address 14 | typedef struct // define data structure to include 15 | { 16 | unsigned long counted; // counter 17 | unsigned long mins; // time (minute and second) 18 | unsigned long secs; 19 | } dataStruct; 20 | dataStruct data; 21 | unsigned long lastTime, nowTime = 0; 22 | int count = 0; 23 | int mins = 0, secs = 0; 24 | 25 | void setup() 26 | { 27 | radio.begin(); // start radio 28 | radio.setChannel(50); // set channel number, 29 | radio.setDataRate(RF24_2MBPS); // data rate and 30 | radio.setPALevel(RF24_PA_HIGH); // power amplifier 31 | radio.setAutoAck(false); // set auto-acknowledge 32 | radio.openWritingPipe(addresses[0]); // initiate data transmit pipe 33 | radio.stopListening(); // set nRF24L01 as transmitter 34 | mins = 0; 35 | secs = 0; 36 | } 37 | 38 | void loop() 39 | { 40 | nowTime = millis(); 41 | if(nowTime - lastTime > 1000) // determine minutes 42 | { // and seconds 43 | secs++; 44 | if(secs > 59) // after 60 seconds 45 | { 46 | secs = 0; // reset second variable 47 | mins++; // increment minute variable 48 | } 49 | data.counted = count; // convert values to data structure 50 | data.mins = mins; 51 | data.secs = secs; 52 | count = 0; // reset counter 53 | lastTime = nowTime; // update time of "second" 54 | } 55 | radio.write(&data, sizeof(data)); // transmit signal 56 | count++; // increment signal counter 57 | } 58 | -------------------------------------------------------------------------------- /Chapter 13/app-to-receive.aia: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/ESP8266-and-ESP32/3f223c897ff3952af75b4a12e4430d87d1927590/Chapter 13/app-to-receive.aia -------------------------------------------------------------------------------- /Chapter 13/app-to-transmit.aia: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/ESP8266-and-ESP32/3f223c897ff3952af75b4a12e4430d87d1927590/Chapter 13/app-to-transmit.aia -------------------------------------------------------------------------------- /Chapter 13/receive-and-transmit.aia: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/ESP8266-and-ESP32/3f223c897ff3952af75b4a12e4430d87d1927590/Chapter 13/receive-and-transmit.aia -------------------------------------------------------------------------------- /Chapter 14/Listing14-1/Listing14-1.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: MAC address 3 | * Description: obtain microcontroller MAC address 4 | * Created on: October 2020 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 14 - ESP-NOW and LoRa communication 8 | ******************************************************************************/ 9 | 10 | #include // include Wi-Fi library 11 | 12 | void setup() 13 | { 14 | Serial.begin(115200); // define Serial Monitor baud rate 15 | Serial.println(WiFi.macAddress()); // get MAC address 16 | } 17 | 18 | void loop() // nothing in loop function 19 | {} 20 | -------------------------------------------------------------------------------- /Chapter 14/Listing14-10/Listing14-10.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: Transmitting LoRa module with feedback 3 | * Description: transmitted and feedback messages deisplayed on OLED screen 4 | * Created on: October 2020 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 14 - ESP-NOW and LoRa communication 8 | ******************************************************************************/ 9 | 10 | #include // include SPI and 11 | #include // LoRa libraries 12 | int CSS = D8; // define SX1278 pins 13 | int RST = -1; // RESET pin 14 | int DIO0 = D2; // interrupt pin 15 | #include // include libraries for OLED 16 | #include 17 | int width = 128; // OLED dimensions 18 | int height = 32; // associate oled with library 19 | Adafruit_SSD1306 oled(width, height, &Wire, -1); 20 | int counter = 0; 21 | unsigned long lastTime; 22 | String packet, recv; 23 | int packetSize; // size of received message 24 | 25 | void setup() 26 | { 27 | digitalPinToInterrupt(DIO0); // set pin as interrupt 28 | LoRa.setPins(CSS, RST, DIO0); // define LoRa module pins 29 | LoRa.setSpreadingFactor(9); // define spreading factor 30 | LoRa.setSignalBandwidth(62.5E3); // set bandwidth to 62.5kHz 31 | while (!LoRa.begin(433E6)) delay(500); // 433MHz transmission 32 | oled.begin(SSD1306_SWITCHCAPVCC, 0x3C); // OLED display I2C address 33 | oled.setTextColor(WHITE); // set font color 34 | oled.setTextSize(2); // text size 1216 pixels 35 | oled.display(); 36 | } 37 | 38 | void loop() 39 | { 40 | if(millis() - lastTime > 5000) // 5s transmission interval 41 | { 42 | screen(); // OLED display function 43 | packet = String(counter); // create packet 44 | LoRa.beginPacket(); // start LoRa transmission 45 | LoRa.print(packet); // send packet 46 | LoRa.endPacket(); // close LoRa transmission 47 | counter++; // increment counter 48 | lastTime = millis(); // update transmission time 49 | } 50 | packetSize = LoRa.parsePacket(); // detect received packet 51 | if (packetSize > 0) 52 | { 53 | recv = ""; // read packet 54 | while(LoRa.available()) recv = recv + ((char)(LoRa.read())); 55 | screen(); // OLED display function 56 | } 57 | }+ 58 | 59 | void screen() // function for OLED display 60 | { 61 | oled.clearDisplay(); 62 | oled.setCursor(0,0); 63 | oled.print("sent ");oled.println(packet); // transmitted value 64 | oled.print(recv); // received message 65 | oled.display(); 66 | } 67 | -------------------------------------------------------------------------------- /Chapter 14/Listing14-11/Listing14-11.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: Characterising LoRa message reception 3 | * Description: received message deisplayed on OLED screen 4 | * Created on: October 2020 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 14 - ESP-NOW and LoRa communication 8 | ******************************************************************************/ 9 | 10 | #include // include SPI and 11 | #include // LoRa libraries 12 | int CSS = D8; // define SX1278 pins 13 | int RST = -1; // RESET pin 14 | int DIO0 = D2; // interrupt pin 15 | int width = 128; // OLED dimensions 16 | int height = 64; 17 | #include // include libraries for OLED 18 | #include 19 | Adafruit_SSD1306 oled(width, height, &Wire, -1); // Reset pin not required 20 | String packet; 21 | int RSSI, packetSize, interval; 22 | float SNR; 23 | unsigned long lastTime = 0; 24 | 25 | void setup() 26 | { 27 | digitalPinToInterrupt(DIO0); // set pin as interrupt 28 | LoRa.setPins(CSS, RST, DIO0); // define LoRa module pins 29 | while (!LoRa.begin(433E6)) delay(500); // 433MHz transmission 30 | oled.begin(SSD1306_SWITCHCAPVCC, 0x3C); // OLED display I2C address 31 | oled.setTextColor(WHITE); // set font color 32 | oled.setTextSize(2); // text size 1216 pixels 33 | oled.display(); 34 | } 35 | 36 | void loop() 37 | { 38 | packetSize = LoRa.parsePacket(); // detect received packet 39 | if (packetSize > 0) 40 | { 41 | interval = round((millis() - lastTime)/1000); // interval (s) 42 | lastTime = millis(); // update message time 43 | packet = ""; // read packet 44 | while(LoRa.available()) packet = packet + ((char)(LoRa.read())); 45 | RSSI = LoRa.packetRssi(); 46 | SNR = LoRa.packetSnr(); // signal : noise 47 | screen(); // OLED display function 48 | LoRa.beginPacket(); // start LoRa transmission 49 | LoRa.print("recv " + packet); // send packet 50 | LoRa.endPacket(); // close LoRa transmission 51 | } 52 | } 53 | 54 | void screen() // function for OLED display 55 | { 56 | oled.clearDisplay(); 57 | oled.setCursor(0,0); 58 | oled.print("lag ");oled.println(interval); // display time since last message 59 | oled.print("RSSI ");oled.println(RSSI); // display interval, RSSI and SNR 60 | oled.print("SNR ");oled.println(SNR); 61 | oled.print("msg ");oled.print(packet); // display received message 62 | oled.display(); 63 | } 64 | -------------------------------------------------------------------------------- /Chapter 14/Listing14-12/Listing14-12.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: Receiving LoRa module and Websocket 3 | * Description: update webpage with received message - see Listing 14-13 4 | * Created on: October 2020 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 14 - ESP-NOW and LoRa communication 8 | ******************************************************************************/ 9 | 10 | #include // include Webserver library 11 | ESP8266WebServer server; // associate server with library 12 | #include // include WebSocket library 13 | WebSocketsServer websocket = WebSocketsServer(81); // set WebSocket port 81 14 | #include "buildpage.h" // webpage AJAX code 15 | char ssid[] = "xxxx"; // change xxxx to Wi-Fi SSID 16 | char password[] = "xxxx"; // change xxxx to Wi-Fi password 17 | String message, json; 18 | int RSSI; 19 | float SNR; 20 | #include // include SPI library 21 | #include // and LoRa library 22 | int CSS = D8; // define SX1278 pins 23 | int RST = -1; // RESET pin 24 | int DIO0 = D2; // interrupt pin 25 | int packetSize; 26 | 27 | void setup() 28 | { 29 | Serial.begin(115200); // define Serial Monitor baud rate 30 | WiFi.begin(ssid, password); // connect and initialise Wi-Fi 31 | while (WiFi.status() != WL_CONNECTED) delay(500); 32 | Serial.print("IP address: "); 33 | Serial.println(WiFi.localIP()); // display web server IP address 34 | server.begin(); 35 | server.on("/", base); // load default webpage 36 | websocket.begin(); // initialise WebSocket 37 | digitalPinToInterrupt(DIO0); // set pin as interrupt 38 | LoRa.setPins(CSS, RST, DIO0); // define LoRa module pins 39 | while (!LoRa.begin(433E6)) delay(500); // 433MHz transmission 40 | Serial.println("LoRa connected"); 41 | } 42 | 43 | void loop() 44 | { 45 | server.handleClient(); // handle HTTP requests 46 | websocket.loop(); // handle WebSocket data 47 | packetSize = LoRa.parsePacket(); // detect received packet 48 | if (packetSize > 0) 49 | { 50 | message = ""; // read packet 51 | while(LoRa.available()) message = message + ((char)(LoRa.read())); 52 | RSSI = LoRa.packetRssi(); 53 | SNR = LoRa.packetSnr(); // signal : noise ratio 54 | JsonConvert(message, RSSI, SNR); // convert to JSON format 55 | websocket.broadcastTXT(json.c_str(), json.length()); 56 | } 57 | } 58 | 59 | String JsonConvert(String val1, int val2, float val3) 60 | { // start with open bracket 61 | json = "{\"var1\": \"" + String(val1) + "\","; // partition with comma 62 | json += " \"var2\": \"" + String(val2) + "\","; 63 | json += " \"var3\": \"" + String(val3) + "\"}"; // end with close bracket 64 | return json; 65 | } 66 | 67 | void base() // function to return HTML code 68 | { 69 | server.send (200, "text/html", page); 70 | } 71 | -------------------------------------------------------------------------------- /Chapter 14/Listing14-13/Listing14-13.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: Websocket and AJAX code for webpage 3 | * Description: update webpage with received message - see Listing 14-12 4 | * Created on: October 2020 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 14 - ESP-NOW and LoRa communication 8 | ******************************************************************************/ 9 | 10 | char page[] PROGMEM = R"( 11 | 12 | 13 | 14 | 15 | ESP8266 16 | 19 | 20 |

LoRa and WebSocket

21 |

last message at

22 |

received

23 |

RSSI 0 dBm

24 |

SNR 0 dB

25 | 43 | 44 | )"; 45 | -------------------------------------------------------------------------------- /Chapter 14/Listing14-2/Listing14-2.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: Example data structure 3 | * Description: Data structure with integers, float and text 4 | * Created on: October 2020 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 14 - ESP-NOW and LoRa communication 8 | ******************************************************************************/ 9 | 10 | typedef struct // define structure to include 11 | { 12 | int count = 5; // two integers, 13 | int total; 14 | float value = 3.14; // a real number 15 | char text[12] = "text"; // and a character array 16 | } dataStruct; 17 | dataStruct payload; // name the structure as payload 18 | -------------------------------------------------------------------------------- /Chapter 14/Listing14-3/Listing14-3.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: Variable, pointer and memory address 3 | * Description: Example use of a pointer 4 | * Created on: October 2020 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 14 - ESP-NOW and LoRa communication 8 | ******************************************************************************/ 9 | 10 | int sum = 25; // allocate value to variable 11 | int *pointer; // define pointer 12 | int number; 13 | 14 | void setup() 15 | { 16 | Serial.begin(115200); 17 | pointer = ∑ // set pointer to address of sum 18 | number = *pointer; // set number to pointer content 19 | Serial.print("\nnumber ");Serial.println(number); 20 | } 21 | 22 | void loop() // nothing in loop function 23 | {} 24 | -------------------------------------------------------------------------------- /Chapter 14/Listing14-4/Listing14-4.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: Transmitter callback 3 | * Description: ESP-NOW transmitter function - see Listing 14-6 4 | * Created on: October 2020 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 14 - ESP-NOW and LoRa communication 8 | ******************************************************************************/ 9 | 10 | void sendData(uint8_t * mac, uint8_t chk) 11 | { 12 | for (int i=0; i<6; i++) // receiver MAC address 13 | { 14 | Serial.printf("%02x", mac[i]); // convert to HEX format 15 | if(i < 5) Serial.print(":"); // include colons 16 | } 17 | Serial.print("\tcallback "); 18 | if(chk == 0) Serial.println("OK "); // transmission received 19 | else Serial.println("fail"); // or not 20 | } 21 | -------------------------------------------------------------------------------- /Chapter 14/Listing14-5/Listing14-5.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: Receiver callback 3 | * Description: ESP-NOW receiver function - see Listing 14-7 4 | * Created on: October 2020 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 14 - ESP-NOW and LoRa communication 8 | ******************************************************************************/ 9 | 10 | void receiveData(uint8_t * mac, uint8_t * data, uint8_t len) 11 | { 12 | memcpy(&payload, data, sizeof(payload)); // copy received data to payload 13 | Serial.print("bytes ");Serial.print(len);Serial.print("\t"); 14 | Serial.print("text ");Serial.println(payload.text); 15 | } 16 | -------------------------------------------------------------------------------- /Chapter 14/Listing14-6/Listing14-6.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: ESP-NOW for a transmitting ESP8266 microcontroller 3 | * Description: ESP-NOW transmitter with data structure 4 | * Created on: October 2020 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 14 - ESP-NOW and LoRa communication 8 | ******************************************************************************/ 9 | 10 | #include // include ESP-NOW library 11 | uint8_t receiveMAC[] = {0x84,0xF3,0xEB,0x0D,0xB5,0xB3}; 12 | typedef struct // receiver MAC address 13 | { 14 | int count = 0; // data structure with 15 | float value = 3.14; // integer, real number 16 | char text[10] = "abcdef"; // and character array 17 | } dataStruct; 18 | dataStruct payload; 19 | int channel = 1; // set transmission channel 20 | int chk; 21 | 22 | void setup() 23 | { 24 | Serial.begin(115200); // define Serial Monitor baud rate 25 | if(esp_now_init() != 0) // initialise ESP-NOW 26 | { 27 | Serial.println("error initialising ESP-NOW"); 28 | return; 29 | } 30 | esp_now_set_self_role(ESP_NOW_ROLE_CONTROLLER); // transmitter device 31 | chk = esp_now_add_peer(receiveMAC, ESP_NOW_ROLE_SLAVE, channel, NULL, 0); 32 | if(chk == 0) Serial.println("receiver added"); // add receiver device 33 | else 34 | { 35 | Serial.println("error adding receiver"); 36 | return; 37 | } 38 | esp_now_register_send_cb(sendData); // call sendData function 39 | } 40 | 41 | void loop() 42 | { 43 | payload.count++; // increment counter 44 | payload.value = payload.value + 1.0; // and real number 45 | if(strcmp(payload.text,"abcdef") == 0) // alternate text 46 | strncpy(payload.text, "xyz", sizeof(payload.text)); 47 | else strcpy(payload.text, "abcdef"); 48 | Serial.print(payload.count); 49 | Serial.print(payload.value); // display transmitted data 50 | Serial.print(payload.text); 51 | chk = esp_now_send(receiveMAC, (uint8_t *) & payload, sizeof(payload)); 52 | Serial.print("\tsent "); 53 | if(chk == 0) Serial.print("OK "); // transmission sent or not 54 | else Serial.println("fail"); 55 | delay(2000); 56 | } 57 | 58 | void sendData(uint8_t * mac, uint8_t chk) // callback function 59 | { 60 | for (int i = 0; i < 6; i++) // display receiving MAC address 61 | { 62 | Serial.printf("%02x", mac[i]); 63 | if (i < 5)Serial.print(":"); 64 | } 65 | Serial.print("\tcallback "); // transmission received or not 66 | if(chk == 0) Serial.println("OK "); 67 | else Serial.println("fail"); 68 | } 69 | -------------------------------------------------------------------------------- /Chapter 14/Listing14-7/Listing14-7.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: ESP-NOW for a receiving ESP8266 microcontroller 3 | * Description: ESP-NOW receiver with data structure 4 | * Created on: October 2020 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 14 - ESP-NOW and LoRa communication 8 | ******************************************************************************/ 9 | 10 | #include // include ESP-NOW library 11 | typedef struct 12 | { 13 | int count; // data structure with 14 | float value; // integer, real number 15 | char text[10]; // and character array 16 | } dataStruct; 17 | dataStruct payload; 18 | int rcv = 0; // counter of received signals 19 | 20 | void setup() 21 | { 22 | Serial.begin(115200); // define Serial Monitor baud rate 23 | if(esp_now_init() != 0) // initialise ESP-NOW 24 | { 25 | Serial.println("error initialising ESP-NOW"); 26 | return; 27 | } 28 | esp_now_set_self_role(ESP_NOW_ROLE_SLAVE); // receiver device 29 | esp_now_register_recv_cb(receiveData); // call receiveData function 30 | } 31 | 32 | void receiveData(uint8_t * mac, uint8_t * data, uint8_t len) 33 | { 34 | rcv++; // increment signal counter 35 | memcpy(&payload, data, sizeof(payload)); // copy received data to payload 36 | for (int i = 0; i < 6; i++) 37 | { // display transmitting MAC address 38 | Serial.printf("%02x", mac[i]); 39 | if (i < 5)Serial.print(":"); 40 | } // display contents of payload 41 | Serial.print("\t"); 42 | Serial.print("received ");Serial.print(rcv);Serial.print("\t"); 43 | Serial.print("bytes ");Serial.print(len);Serial.print("\t"); 44 | Serial.print("count ");Serial.print(payload.count);Serial.print("\t"); 45 | Serial.print("value ");Serial.print(payload.value);Serial.print("\t"); 46 | Serial.print("text ");Serial.println(payload.text); 47 | } 48 | 49 | void loop() // nothing in loop function 50 | {} 51 | -------------------------------------------------------------------------------- /Chapter 14/Listing14-9/Listing14-9.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: Websocket webpage AJAX code 3 | * Description: update webpage with received structure data - see Listing 14-8 4 | * Created on: October 2020 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 14 - ESP-NOW and LoRa communication 8 | ******************************************************************************/ 9 | 10 | char page[] PROGMEM = R"( 11 | 12 | 13 | 14 | 15 | ESP-NOW 16 | 19 | 20 |

ESP-NOW with ESP8266

21 |

last message at

22 |

received from

23 |

counter 0

24 |

number 0

25 |

message

26 | 45 | 46 | )"; 47 | -------------------------------------------------------------------------------- /Chapter 15/Listing15-1/Listing15-1.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: Transmit message with RH_ASK library 3 | * Description: Transmit numbers as text 4 | * Created on: October 2020 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 15 - Radio Frequency Communication 8 | ******************************************************************************/ 9 | 10 | #include // include the RH_ASK library 11 | #include // SPI library required to compile 12 | RH_ASK rf (2000, D2, D1, 0); // associate rf with RH_ASK lib 13 | int LEDpin = D3; // define LED pin 14 | String text[] = {"abcdef", "ijkl", "rst"}; // strings of different lengths 15 | const char * msg; // pointer to array with message 16 | String message; 17 | int timelag = 2000; // interval between transmissions 18 | int LED = 0; // initial LED state 19 | int val, len, spd; 20 | 21 | void setup() 22 | { 23 | Serial.begin(115200); // define Serial Monitor baud rate 24 | rf.init(); // initialise radio transmission 25 | pinMode(LEDpin, OUTPUT); // define LED pin as output 26 | len = rf.maxMessageLength(); // get maximum message length 27 | spd = rf.speed(); // get transmission speed 28 | Serial.print("max message length: "); 29 | Serial.println(len); // display message length 30 | Serial.print("transmission speed: "); // and transmission speed 31 | Serial.println(spd); 32 | } 33 | 34 | void loop() 35 | { 36 | val = millis()/timelag; // transmission number 37 | message = text[val%3] + "," + String(1.2*val) + "," + String(val) + ","; 38 | Serial.println(message); // display transmitted string 39 | msg = message.c_str(); // convert string 40 | rf.send((uint8_t *)msg, strlen(msg)); // transmit signal 41 | rf.waitPacketSent(); // wait for transmission to finish 42 | LED = 1 - LED; 43 | digitalWrite(LEDpin, LED); // turn on or off LED 44 | delay(timelag); 45 | } 46 | -------------------------------------------------------------------------------- /Chapter 15/Listing15-2/Listing15-2.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: Receive message with RH_ASK library 3 | * Description: Receive numbers as text 4 | * Created on: October 2020 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 15 - Radio Frequency Communication 8 | ******************************************************************************/ 9 | 10 | #include // include the RH_ASK library 11 | #include // SPI library required to compile 12 | RH_ASK rf (2000, D2, D1, 0); // associate rf with RH_ASK lib 13 | int LEDpin = D3; // define LED pin 14 | uint8_t msg[RH_ASK_MAX_MESSAGE_LEN]; // maximum message length 15 | const int nItem = 3; // number of items in message 16 | String text[nItem]; // define text array 17 | int comma[nItem+1]; // comma positions in message 18 | int LED = 0; // initial LED state 19 | String message; 20 | float valFlt; 21 | int valInt; 22 | 23 | void setup() 24 | { 25 | Serial.begin(115200); // define Serial Monitor baud rate 26 | rf.init(); // initialise radio transmission 27 | pinMode(LEDpin, OUTPUT); // define LED pin as output 28 | } 29 | 30 | void loop() 31 | { 32 | uint8_t msglen = sizeof(msg); // message length based on new message 33 | if (rf.recv(msg, &msglen)) // message of correct length available 34 | { 35 | message = ""; // increment message with each character 36 | for (int i=0; i // include the rc-switch library 11 | RCSwitch rc = RCSwitch(); // associate rc with rc-switch lib 12 | int LEDpin = D3; // define LED pin and state 13 | int LED = 0; 14 | unsigned long value; 15 | 16 | void setup() 17 | { 18 | Serial.begin(115200); // define Serial Monitor baud rate 19 | digitalPinToInterrupt(D2); // set pin as interrupt 20 | rc.enableReceive(D2); // receive data on interrupt pin 21 | pinMode(LEDpin, OUTPUT); // define LED pin as output 22 | } 23 | 24 | void loop() 25 | { 26 | if (rc.available()) // if a signal is received 27 | { 28 | value = rc.getReceivedValue(); // signal in decimal format 29 | if (value != 0) // non-zero signal value 30 | { 31 | Serial.print("Decimal ");Serial.print(value); 32 | Serial.print(" ("); 33 | Serial.print(rc.getReceivedBitlength()); // signal bit length 34 | Serial.print("bit)\tProtocol "); // print a tab between text 35 | Serial.println(rc.getReceivedProtocol()); // signal protocol class 36 | LED = 1 - LED; 37 | digitalWrite(LEDpin, LED); // turn on or off the LED 38 | } 39 | else Serial.println("Unknown encoding"); 40 | rc.resetAvailable(); // ready to receive signal 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Chapter 15/Listing15-5/Listing15-5.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: Transmit joystick signal to control servo motors and laser 3 | * Description: Transmit numbers as text with RH_ASK library 4 | * Created on: October 2020 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 15 - Radio Frequency Communication 8 | ******************************************************************************/ 9 | 10 | #include // include the RH_ASK library 11 | #include // SPI library required to compile 12 | RH_ASK rf; // associate rf with RH_ASK lib 13 | int timelag = 50; // interval between transmissions 14 | int switchPin = A0; // joystick switch pin 15 | int LRpin = A1; // left-right joystick pin 16 | int FBpin = A2; // forward-backward joystick pin 17 | int FB, LR, SW; 18 | const char * msg; 19 | String message; 20 | 21 | void setup() 22 | { 23 | rf.init(); // initialise radio transmission 24 | } 25 | 26 | void loop() 27 | { // string for joystick forward-backward, left-right and switch state 28 | FB = analogRead(FBpin); 29 | LR = analogRead(LRpin); // get joystick position 30 | SW = digitalRead(switchPin); // and switch state 31 | message = String(FB) +","+ String(LR) + "," + String(SW) + ","; 32 | msg = message.c_str(); // convert string 33 | rf.send((uint8_t *)msg, strlen(msg)); // transmit message 34 | rf.waitPacketSent(); // wait for transmission to finish 35 | delay(timelag); // delay between transmissions 36 | } 37 | -------------------------------------------------------------------------------- /Chapter 15/Listing15-6/Listing15-6.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: Receive signal with joystick positions to control servo motors and laser 3 | * Description: Receive numbers as text with RH_ASK library 4 | * Created on: October 2020 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 15 - Radio Frequency Communication 8 | ******************************************************************************/ 9 | 10 | #include // include the RH_ASK library 11 | #include // SPI library required to compile 12 | #include // include servo library 13 | RH_ASK rf (2000, D2, D1, 0); // associate rf with RH_ASK lib 14 | Servo servoFB; // associate servoFB and servoLR 15 | Servo servoLR; // with servo library 16 | int FBpin = D6; // forward-backward servo pin 17 | int LRpin = D7; // left-right servo pin 18 | int laserPin = D0; // define laser pin 19 | uint8_t msg[RH_ASK_MAX_MESSAGE_LEN]; 20 | const int nItem = 3; // number of items in message 21 | String text[nItem]; // array of strings 22 | int comma[nItem+1]; // array of comma positions 23 | String string; 24 | int laser, FB, LR; 25 | 26 | void setup() 27 | { 28 | rf.init(); // initialise radio transmission 29 | servoFB.attach(FBpin); // initialise servo motors 30 | servoLR.attach(LRpin); 31 | pinMode(laserPin, OUTPUT); // define laser pin as output 32 | } 33 | 34 | void loop() 35 | { 36 | uint8_t msglen = sizeof(msg); // define message length based on new message 37 | if (rf.recv(msg, &msglen)) // message of correct length available 38 | { 39 | string = ""; // increment string by each message character 40 | for (int i=0; i // include the rc-switch library 11 | RCSwitch rc = RCSwitch(); // associate rc with rc-switch lib 12 | int LEDpin = D3; // LED to change state 13 | int LEDrelayPin = D0; // LED associated with relay 14 | int relayPin = D7; // define MOSFET/relay pin 15 | unsigned long value; 16 | 17 | void setup() 18 | { 19 | Serial.begin(9600); // define Serial Monitor baud rate 20 | digitalPinToInterrupt(D2); // set pin as interrupt 21 | rc.enableReceive(D2); // receive data on interrupt pin 22 | // digitalWrite(relayPin, HIGH); // set relayPin HIGH before 23 | pinMode(relayPin, OUTPUT); // defining relayPin 24 | pinMode(LEDpin, OUTPUT); 25 | pinMode(LEDrelayPin, OUTPUT); 26 | } 27 | 28 | void loop() 29 | { 30 | if (rc.available()) // if a signal is received 31 | { 32 | value = rc.getReceivedValue(); 33 | if (value != 0) // signal value not equal to zero 34 | { // display signal value 35 | Serial.print("code ");Serial.print(value); 36 | if(value == 3163908) // Light button pressed 37 | { 38 | Serial.print("\tchange LED"); // display action 39 | digitalWrite(LEDpin, !digitalRead(LEDpin)); // turn on or off LED 40 | } 41 | else if(value == 3163909) // Bright+ button pressed 42 | { 43 | Serial.print("\trelay on"); 44 | digitalWrite(LEDrelayPin, HIGH); // turn on relay LED 45 | digitalWrite(relayPin, HIGH); // turn on relay 46 | } 47 | else if (value == 3163910) // Bright- button pressed 48 | { 49 | Serial.print("\trelay off"); 50 | digitalWrite(LEDrelayPin, LOW); // turn off relay LED 51 | digitalWrite(relayPin, LOW); // turn off relay 52 | } 53 | else Serial.print("\tno action"); 54 | Serial.print("\tLED "); 55 | Serial.print(digitalRead(LEDpin)); // display LED and relay states 56 | Serial.print("\trelay "); 57 | Serial.println(digitalRead(relayPin)); 58 | } 59 | else Serial.println("Unknown encoding"); 60 | rc.resetAvailable(); // ready to receive new signal 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /Chapter 16/Listing16-1/Listing16-1.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: AD9833 sine and triangle wave generator 3 | * Description: Generate waves with MD-AD9833 library 4 | * Created on: October 2020 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 16 - Signal generation 8 | ******************************************************************************/ 9 | 10 | #include // include SPI library 11 | #include // include MD-AD9833 library 12 | int FSYNC = D0; // define data synchronisation pin 13 | MD_AD9833 AD(FSYNC); 14 | MD_AD9833::channel_t chan; // library channel variable 15 | MD_AD9833::mode_t mode; // library signal mode variable 16 | unsigned long freq; 17 | 18 | void setup() 19 | { 20 | AD.begin(); // initialise library 21 | chan = MD_AD9833::CHAN_0; // set channel as 0 or 1 22 | AD.setActiveFrequency(chan); // activate signal generator 23 | } 24 | 25 | void loop() 26 | { 27 | wave('s', 30000, 5000); // call sine and triangle 28 | wave('t', 20000, 5000); // wave display function 29 | } 30 | 31 | void wave(char shape, unsigned long freq, int timeint) 32 | { 33 | if(shape == 's') mode = MD_AD9833::MODE_SINE; // sine wave 34 | else if(shape == 't') mode = MD_AD9833::MODE_TRIANGLE; // triangle wave 35 | AD.setMode(mode); // set the wave form 36 | AD.setFrequency(chan, freq); // set signal frequency for channel 37 | delay(timeint); // time to generate signal 38 | clear(); // call clear function 39 | } 40 | 41 | void clear() // function to clear signal 42 | { 43 | mode = MD_AD9833::MODE_OFF; // set wave mode to off 44 | AD.setMode(mode); // turn off wave generation 45 | delay(500); // time with no signal 46 | } 47 | -------------------------------------------------------------------------------- /Chapter 16/Listing16-2/Listing16-2.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: R-2R digital to analog converter 3 | * Description: R-2R resistor ladder 8-bit DAC 4 | * Created on: October 2020 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 16 - Signal generation 8 | ******************************************************************************/ 9 | 10 | int dataPin = D5; // shift register data 11 | int latchPin = D6; // latch and clock pins 12 | int clockPin = D7; 13 | int Vin; // voltage on analog pin 14 | float voltage, predict; // voltage divider effect and 15 | float voltDivid = 1000.0*(10+220+100)/100; // adjustment to mV 16 | 17 | void setup() 18 | { 19 | Serial.begin(115200); // define Serial Monitor baud rate 20 | pinMode(dataPin, OUTPUT); // shift register pins as output 21 | pinMode(latchPin, OUTPUT); 22 | pinMode(clockPin, OUTPUT); 23 | } 24 | 25 | void loop() // nothing in loop function 26 | { 27 | for (int i=0; i<256; i=i+50) // incremental increases 28 | { 29 | digitalWrite(latchPin, LOW); // start loading shift register 30 | shiftOut(dataPin, clockPin, MSBFIRST, i); // load 8-bit number 31 | digitalWrite(latchPin, HIGH); // end loading shift register 32 | Vin = analogRead(A0); // read R-2R ladder voltage 33 | voltage = Vin * voltDivid / 1024.0; // scaled R-2R ladder voltage 34 | predict = i * 3300.0 / 256; // predicted output voltage 35 | Serial.print(i);Serial.print("\t"); 36 | Serial.print(Vin);Serial.print("\t"); // display results 37 | Serial.print(voltage,0);Serial.print("\t"); 38 | Serial.println(predict,0); 39 | delay(200); 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /Chapter 16/Listing16-3/Listing16-3.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: Generating a sine wave with R-2R ladder 8-bit DAC 3 | * Description: generate sine waves 4 | * Created on: October 2020 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 16 - Signal generation 8 | ******************************************************************************/ 9 | 10 | int dataPin = D5; // shift register data 11 | int latchPin = D6; // latch and clock pins 12 | int clockPin = D7; 13 | int count = 0; 14 | float sum, angle, Hz; 15 | unsigned long lastTime; 16 | int val, sign, mult, cycleTime; 17 | 18 | void setup() 19 | { 20 | Serial.begin(115200); // define Serial Monitor baud rate 21 | pinMode(dataPin, OUTPUT); // shift register pins as output 22 | pinMode(latchPin, OUTPUT); 23 | pinMode(clockPin, OUTPUT); 24 | } 25 | 26 | void loop() 27 | { 28 | mult = 20.0*analogRead(A0)/1023.0; // scale potentiometer value 29 | for (int deg=0; deg<360; deg=deg+mult) // cycle through 360° 30 | { 31 | angle = deg*PI/180.0; // convert degrees to radians 32 | sum = sin(angle); 33 | val = round(128+120.0*sum); // scaled sine wave value 34 | digitalWrite(latchPin, LOW); // start loading shift register 35 | shiftOut(dataPin, clockPin, MSBFIRST, val); // load 8-bit number 36 | digitalWrite(latchPin, HIGH); // end loading shift register 37 | } 38 | count ++; 39 | if(count > 999) // display every 1000 cycles 40 | { 41 | cycleTime = millis() - lastTime; // time (ms) for cycle 42 | Hz = 1000.0 * count / cycleTime; // frequency (Hz) 43 | Serial.print(mult);Serial.print("\t"); 44 | Serial.print(Hz);Serial.print("Hz\t"); 45 | Serial.print(1.0*cycleTime/count);Serial.println("ms"); 46 | count = 0; // reset counter 47 | lastTime = millis(); // reset timer 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /Chapter 16/Listing16-4/Listing16-4.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: Generating a sine wave with ESP32 DAC 3 | * Description: generate sine waves 4 | * Created on: October 2020 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 16 - Signal generation 8 | ******************************************************************************/ 9 | 10 | int DACpin = DAC1; // DAC pin on GPIO 25 11 | float angle; 12 | int val; 13 | 14 | void setup() // nothing in setup function 15 | {} 16 | 17 | void loop() 18 | { 19 | for (int deg=0; deg<360; deg++) // cycle through 360° 20 | { 21 | angle = deg*PI/180.0; // convert degrees to radians 22 | val = round(128+100.0*sin(angle)); // scaled sine wave value 23 | dacWrite(DACpin, val); // output voltage 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Chapter 16/Listing16-5/Listing16-5.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: I2C scanner 3 | * Description: Scan I2C devices to determine I2C address 4 | * Created on: October 2020 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 16 - Signal generation 8 | ******************************************************************************/ 9 | 10 | #include // include Wire library 11 | int device = 0; // set device counter 12 | 13 | void setup() 14 | { 15 | Serial.begin (115200); // define Serial Monitor baud rate 16 | Wire.begin(); // start I2C bus 17 | for (int i=8; i<127; i++) // scan through channels 8 to 126 18 | { 19 | Wire.beginTransmission (i); // transmit to device at address i 20 | if (Wire.endTransmission () == 0) // device response to transmission 21 | { 22 | Serial.print("Address 0x"); 23 | Serial.println(i, HEX); // display I2C address in HEX 24 | device++; // increment device count 25 | delay(10); 26 | } 27 | } 28 | Serial.print(device); // display device count 29 | Serial.println(" device found"); 30 | } 31 | 32 | void loop() // nothing in loop function 33 | {} 34 | -------------------------------------------------------------------------------- /Chapter 16/Listing16-6/Listing16-6.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: Sine wave with MCP4725 12-bit DAC module 3 | * Description: generate sine waves 4 | * Created on: October 2020 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 16 - Signal generation 8 | ******************************************************************************/ 9 | 10 | #include // include Adafruit MCP4725 lib 11 | Adafruit_MCP4725 dac; // associate dac and MCP4725 lib 12 | float voltDivid = 3200; // voltage divider adjustment 13 | float VCC = 3300; // operating voltage 14 | int flag = 0; // flag to switch to sine wave 15 | float predict, voltage, value; 16 | int Vin; 17 | 18 | void setup() 19 | { 20 | Serial.begin(115200); // define Serial Monitor baud rate 21 | dac.begin(0x60); // I2C address of MCP4725 22 | } 23 | 24 | void loop() 25 | { 26 | if(flag < 1) 27 | { 28 | for(int i=0; i<4096; i=i+50) 29 | { 30 | dac.setVoltage(i, false); // set output voltage 31 | Vin = analogRead(A0); // read DAC voltage 32 | voltage = Vin * voltDivid /1024.0; // scaled output voltage 33 | predict = i * VCC / 4096.0; // predicted output voltage 34 | Serial.print(voltage);Serial.print("\t"); 35 | Serial.println(predict); // display voltages 36 | } 37 | delay(2000); 38 | flag = 1; // switch to sine wave only 39 | } 40 | for (int deg=0; deg<360; deg++) // generate sine wave 41 | { 42 | value = 2047.0*(sin(deg*PI/180.0)+1); // scaled sine wave value 43 | dac.setVoltage(value, false); // set output voltage 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /Chapter 16/Listing16-7/Listing16-7.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: Storing sine wave values in flash memory 3 | * Description: generate sine waves 4 | * Created on: October 2020 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 16 - Signal generation 8 | ******************************************************************************/ 9 | 10 | #include // include Adafruit MCP4725 lib 11 | Adafruit_MCP4725 dac; // associate dac and MCP4725 lib 12 | const uint16_t lookup[] PROGMEM = { // sine wave in flash memory 13 | 2047,2402,2747,3071,3363,3615,3820,3971,4063,4094, 14 | 4063,3971,3820,3615,3363,3071,2747,2402,2047,1692, 15 | 1347,1024, 731, 479, 274, 123, 31, 0, 31, 123, 16 | 274, 479, 731,1024,1347,1692 // 2047(sin(x/180) + 1) 17 | }; 18 | int value, cycle; 19 | unsigned long lastTime = 0; 20 | float freq; 21 | 22 | void setup() 23 | { 24 | Serial.begin(115200); // define Serial Monitor baud rate 25 | dac.begin(0x60); // I2C address of MCP4725 26 | } 27 | 28 | void loop() 29 | { 30 | lastTime = millis(); // start timer 31 | while (cycle < 500) // sine wave for 500 cycles 32 | { 33 | for (int i=0; i<36; i++) 34 | { 35 | value = pgm_read_word(lookup+i); // values from flash memory 36 | dac.setVoltage(value, false); // set output voltage 37 | } 38 | cycle++; 39 | yield(); // required to prevent timeout 40 | } 41 | freq = 1000 * 500.0/(millis() - lastTime); // wave frequency 42 | Serial.print("lookup ");Serial.print(freq); 43 | cycle = 0; 44 | 45 | lastTime = millis(); 46 | while (cycle < 500) 47 | { 48 | for (int deg=0; deg<360; deg=deg+10) // generate sine wave 49 | { 50 | value = 2047.0*(sin(deg*PI/180.0)+1); // scaled sine wave value 51 | dac.setVoltage(value, false); // set output voltage 52 | } 53 | cycle++; 54 | yield(); 55 | } 56 | freq = 1000 * 500.0/(millis()-lastTime); 57 | Serial.print("\tcalc ");Serial.println(freq); 58 | cycle = 0; 59 | } 60 | -------------------------------------------------------------------------------- /Chapter 16/Table16-1_left-side/Table16-1_left-side.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: PWM with ESP8266 microcontroller 3 | * Description: analogWrite function to control PWM signal 4 | * Created on: October 2020 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 16 - Signal generation 8 | ******************************************************************************/ 9 | 10 | int wave1Pin = D1, wave2Pin = D2; 11 | int freq1 = 10000, freq2 = 2000; 12 | float duty1, duty2; 13 | 14 | void setup() 15 | { 16 | pinMode(wave1Pin, OUTPUT); 17 | pinMode(wave2Pin, OUTPUT); 18 | duty1 = 0.8*1023; 19 | duty2 = 0.4*1023; 20 | } 21 | 22 | void loop() 23 | { 24 | analogWriteFreq(freq1); 25 | analogWrite(wave1Pin, duty1); 26 | analogWriteFreq(freq2); 27 | analogWrite(wave2Pin, duty2); 28 | } 29 | -------------------------------------------------------------------------------- /Chapter 16/Table16-1_right-side/Table16-1_right-side.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: PWM with ESP32 microcontroller 3 | * Description: lcdWrite function to control PWM signal 4 | * Created on: October 2020 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 16 - Signal generation 8 | ******************************************************************************/ 9 | 10 | int wave1Pin = 25, wave2Pin = 26; 11 | int freq1 = 10000, freq2 = 2000; 12 | float duty1, duty2; 13 | int channel1 = 1, channel2 = 2; 14 | int resolution = 10; 15 | 16 | void setup() 17 | { 18 | pinMode(wave1Pin, OUTPUT); 19 | pinMode(wave2Pin, OUTPUT); 20 | ledcAttachPin(wave1Pin, channel1); 21 | ledcAttachPin(wave2Pin, channel2); 22 | ledcSetup(channel1, freq1, resolution); 23 | ledcSetup(channel2, freq2, resolution); 24 | duty1 = 0.8*1023; 25 | duty2 = 0.4*1023; 26 | } 27 | 28 | void loop() 29 | { 30 | ledcWrite(channel1, duty1); 31 | ledcWrite(channel2, duty2); 32 | } 33 | -------------------------------------------------------------------------------- /Chapter 18/Listing18-1/Listing18-1.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: Battery voltage measurement 3 | * Description: Display voltage and battery figure on OLED screen 4 | * Created on: October 2020 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 18 - Measuring electricity 8 | ******************************************************************************/ 9 | 10 | #include // Adafruit SSD1306 library 11 | int width = 128; // OLED screen size 12 | int height = 32; // associate oled with SSD1306 13 | Adafruit_SSD1306 oled(width, height, &Wire, -1); 14 | int ADCpin = A0; // define analog input pin 15 | float maxVolt = 10.24; // maximum battery voltage 16 | float voltage; 17 | int battery; 18 | 19 | void setup() 20 | { 21 | oled.begin(SSD1306_SWITCHCAPVCC, 0x3C); // OLED display and I2C address 22 | oled.clearDisplay(); // clear OLED display 23 | oled.setTextColor(WHITE); // set font color 24 | oled.setTextSize(2); // set font size (1, 2, 3 or 4) 25 | oled.display(); // start display instructions 26 | } 27 | 28 | void loop() 29 | { 30 | voltage = analogRead(ADCpin)*maxVolt/1024.0; // calculate battery voltage 31 | oled.clearDisplay(); 32 | oled.setCursor(0,0); // position cursor at (0, 0) 33 | oled.print(voltage); 34 | oled.print("V"); // display battery voltage 35 | oled.fillRect(0, 20, 45, 12, WHITE); // battery frame 2 pixels width 36 | battery = 41*voltage/maxVolt; // full battery section 37 | battery = constrain(battery, 0, 41); 38 | oled.fillRect(2+battery, 22, 41-battery, 8, BLACK); // empty battery section 39 | oled.fillRect(45, 23, 3, 6, WHITE); // battery top 40 | oled.display(); 41 | delay(2000); // delay 2s between readings 42 | } 43 | -------------------------------------------------------------------------------- /Chapter 18/Listing18-2/Listing18-2.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: Battery voltage with and without load measurement 3 | * Description: Display voltages on OLED screen 4 | * Created on: October 2020 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 18 - Measuring electricity 8 | ******************************************************************************/ 9 | 10 | #include // SSD1306 library for OLED 11 | int width = 128; // OLED screen size 12 | int height = 32; // associate oled with SSD1306 13 | Adafruit_SSD1306 oled(width, height, &Wire, -1); 14 | int basePin = D6; // BJT base pin 15 | int collPin = A0; // BJT collector pin 16 | unsigned long sum; 17 | int reps = 10; // number of repeat measurements 18 | float maxVolt = 3.2; // 3.2V maximum voltage 19 | float Vbatt, Vload; 20 | 21 | void setup() 22 | { 23 | pinMode(basePin, OUTPUT); // define basePin as OUTPUT 24 | oled.begin(SSD1306_SWITCHCAPVCC, 0x3C); // OLED I2C address 25 | oled.clearDisplay(); // clear OLED display 26 | oled.setTextColor(WHITE); // OLED font color 27 | oled.setTextSize(1); // font size 1 character 68 pixels 28 | oled.display(); // start display instructions 29 | } 30 | 31 | void loop() 32 | { 33 | readings(LOW); // read BJT collector pin, BJT off 34 | Vbatt = maxVolt*sum/(reps*1024.0); // battery voltage 35 | if(Vbatt > 0.1) 36 | { 37 | readings(HIGH); // read BJT collector pin, BJT on 38 | Vload = maxVolt*sum/(reps*1024.0); // battery voltage with load 39 | screen(); // call screen function 40 | } 41 | else 42 | { 43 | oled.clearDisplay(); // clear OLED when 44 | oled.display(); // no battery voltage 45 | } 46 | delay(2000); // delay between measurements 47 | } 48 | 49 | void readings(int pinState) // function to measure BJT pin 50 | { 51 | digitalWrite(basePin, pinState); // BJT base pin turned on or off 52 | sum = 0; 53 | for (int i=0; i // Adafruit SSD1306 library 11 | int width = 128; // OLED screen size 12 | int height = 32; // associate oled with SSD1306 13 | Adafruit_SSD1306 oled(width, height, &Wire, -1); 14 | int resistPin = A0; // analog input pin 15 | int pin[] = {D5, D6, D7}; // pins for known resistor 16 | float known[] = {1000.0, 4700.0, 10000.0}; // known resistor values 17 | float resist, reading; 18 | 19 | void setup() 20 | { 21 | oled.begin(SSD1306_SWITCHCAPVCC, 0x3C); // OLED display and I2C address 22 | oled.clearDisplay(); // clear OLED display 23 | oled.setTextColor(WHITE); // set font color 24 | oled.setTextSize(1); // set font size (1, 2, 3 or 4) 25 | oled.display(); // update display instructions 26 | // set known resistor pins to INPUT 27 | for (int i=0; i<3; i++) pinMode(pin[i], INPUT); 28 | } 29 | 30 | void loop() 31 | { 32 | oled.clearDisplay(); // clear OLED display 33 | oled.setCursor(0,0); 34 | oled.print("known ADC predict"); // header on OLED screen 35 | for (int i=0; i<3; i++) // for each known resistor 36 | { 37 | pinMode(pin[i], OUTPUT); // set known resistor pin 38 | digitalWrite(pin[i], HIGH); // to OUTPUT and to HIGH 39 | reading = analogRead(resistPin); // voltage divider reading 40 | if(reading < 10 || reading > 1013) reading = 0; // constrain ADC reading 41 | resist = known[i]*reading/(1024.0-reading); // calculate resistance 42 | pinMode(pin[i], INPUT); // reset known resistor pin to INPUT 43 | oled.setCursor(1, (i+1)*8); // OLED column 1, row 8, 16, 24 44 | oled.print(known[i],0); // display known resistor 45 | oled.setCursor(50, (i+1)*8); 46 | oled.print(reading,0); // display ADC reading 47 | oled.setCursor(90, (i+1)*8); 48 | oled.print(resist,0); // display calculated resistance 49 | oled.display(); 50 | } 51 | delay(5000); 52 | } 53 | -------------------------------------------------------------------------------- /Chapter 18/Listing18-4/Listing18-4.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: Capacitance meter 3 | * Description: Measure capacitor charging time 4 | * Created on: October 2020 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 18 - Measuring electricity 8 | ******************************************************************************/ 9 | 10 | #include // Adafruit SSD1306 library 11 | int width = 128; // OLED screen size 12 | int height = 32; // associate oled with SSD1306 13 | Adafruit_SSD1306 oled(width, height, &Wire, -1); 14 | int capPin = A0; // capacitor positive pin 15 | int chargePin = D7; // pin with 10k charge resistor 16 | int dischargePin = D6; // 220 discharge resistor pin 17 | float resistor = 10000.0; // 10k charge resistor 18 | unsigned long startTime; 19 | float mF, uF, nF; // uF for microF (Greek letter ) 20 | 21 | void setup() 22 | { 23 | oled.begin(SSD1306_SWITCHCAPVCC, 0x3C); // OLED display and I2C address 24 | oled.clearDisplay(); // clear OLED display 25 | oled.setTextColor(WHITE); // set font color 26 | oled.setTextSize(2); // set font size (1, 2, 3 or 4) 27 | oled.display(); // update display instructions 28 | pinMode(chargePin, OUTPUT); // set charge pin 29 | digitalWrite(chargePin, LOW); // as OUTPUT and to 0V 30 | } 31 | 32 | void loop() 33 | { 34 | oled.clearDisplay(); 35 | oled.setCursor(0,0); 36 | digitalWrite(chargePin, HIGH); // charge pin to reference voltage 37 | startTime = millis(); // start timing charging capacitor 38 | while(analogRead(capPin) < 648) {} // do nothing while ADC < 648 39 | mF = (millis() - startTime) / resistor; // calculate capacitance = time/R 40 | uF = 1000.0 * mF; // change millifarad to microfarad 41 | if (uF > 1) 42 | { 43 | if (uF < 10) oled.print(uF, 1); // display capacitance with 1DP 44 | else oled.print(uF, 0); // or 0DP depending on value 45 | oled.print(" uF"); 46 | } 47 | else 48 | { 49 | nF = 1000.0 * uF; // convert to nanofarad 50 | if (nF > 10) // only display if value > 10nF 51 | { 52 | oled.print(nF, 0); // display capacitance 53 | oled.print(" nF"); 54 | } 55 | } 56 | digitalWrite(chargePin, LOW); // set charge pin to 0V 57 | pinMode(dischargePin, OUTPUT); // set discharge pin 58 | digitalWrite(dischargePin, LOW); // to OUTPUT and 0V 59 | while(analogRead(capPin) > 0) {} // do nothing while capacitor discharges 60 | pinMode(dischargePin, INPUT); // set discharge pin to INPUT 61 | oled.display(); 62 | delay(2000); // to ensure no current flows 63 | } 64 | -------------------------------------------------------------------------------- /Chapter 18/Listing18-5/Listing18-5.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: Ammeter with shunt resistor 3 | * Description: Display current on OLED screen 4 | * Created on: October 2020 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 18 - Measuring electricity 8 | ******************************************************************************/ 9 | 10 | #include // Adafruit SSD1306 library 11 | int width = 128; // OLED screen size 12 | int height = 32; // associate oled with SSD1306 13 | Adafruit_SSD1306 oled(width, height, &Wire, -1); 14 | int ADCpin = A0; 15 | unsigned long ADC; 16 | int Rfeedback = 100000; // feedback resistor value 17 | int RGND = 2200; // resistor GND value 18 | float current, opAmpmV, shuntmV, gain; 19 | 20 | void setup() 21 | { 22 | Serial.begin(115200); 23 | oled.begin(SSD1306_SWITCHCAPVCC, 0x3C); // OLED display and I2C address 24 | oled.clearDisplay(); // clear OLED display 25 | oled.setTextColor(WHITE); // set font color 26 | oled.setTextSize(1); // set font size (1, 2, 3 or 4) 27 | oled.display(); // update display instructions 28 | gain = 1.0 + Rfeedback/RGND; // calculate op amp gain 29 | } 30 | 31 | void loop() 32 | { 33 | ADC = 0; 34 | for (int i=0; i<100; i++) // repeated analog readings 35 | { 36 | ADC = ADC + analogRead(ADCpin); 37 | delay(10); 38 | } 39 | ADC = ADC/100; // average of analog readings 40 | opAmpmV = ADC*3200.0/1024; // op amp output voltage 41 | shuntmV = opAmpmV / gain; // voltage on shunt 42 | current = 100.0 * shuntmV; // shunt mV to current in mA 43 | oled.clearDisplay(); 44 | oled.setCursor(0,0); // display results on OLED 45 | oled.print("current ");oled.print(current,0); oled.println(" mA"); 46 | oled.print("shunt mV ");oled.println(shuntmV,0); 47 | oled.print("opamp mV ");oled.println(opAmpmV,0); 48 | oled.print("ADC ");oled.println(ADC); 49 | oled.display(); 50 | delay(1000); 51 | } 52 | -------------------------------------------------------------------------------- /Chapter 18/Listing18-6/Listing18-6.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: Current sensor MAX471 and ESP8266 development board 3 | * Description: Display current on OLED screen 4 | * Created on: October 2020 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 18 - Measuring electricity 8 | ******************************************************************************/ 9 | 10 | #include // Adafruit SSD1306 library 11 | int width = 128; // OLED screen size 12 | int height = 32; // associate oled with SSD1306 13 | Adafruit_SSD1306 oled(width, height, &Wire, -1); 14 | int currentPin = A0; // analog input pin 15 | float current; 16 | 17 | void setup() 18 | { 19 | oled.begin(SSD1306_SWITCHCAPVCC, 0x3C); // OLED I2C address 20 | oled.clearDisplay(); // clear OLED display 21 | oled.setTextColor(WHITE); // set font color 22 | oled.setTextSize(3); // set font size (1, 2, 3 or 4) 23 | oled.display(); // update display instructions 24 | } 25 | 26 | void loop() 27 | { 28 | current = analogRead(currentPin); // analog MAX471 reading 29 | current = 1000*current*3.2/1024; // convert to current 30 | oled.clearDisplay(); 31 | oled.setCursor(0,0); // position cursor 32 | oled.print(current,0); oled.print(" mA"); // display current 33 | oled.display(); 34 | delay(5000); 35 | } 36 | -------------------------------------------------------------------------------- /Chapter 18/Listing18-7/Listing18-7.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: Current sensor (INA219) 3 | * Description: Display current on OLED screen 4 | * Created on: October 2020 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 18 - Measuring electricity 8 | ******************************************************************************/ 9 | 10 | #include // define Adafruit_INA219 lib 11 | Adafruit_INA219 ina219; // default I2C, associate ina219 with lib 12 | #include // Adafruit SSD1306 library 13 | int width = 128; // OLED screen size 14 | int height = 32; // associate oled with SSD1306 15 | Adafruit_SSD1306 oled(width, height, &Wire, -1); 16 | float shunt, load, supply, current, power; 17 | float energy = 0; 18 | 19 | void setup() 20 | { 21 | ina219.begin(); 22 | // ina219.setCalibration_32V_2A(); // default precision option 23 | // ina219.setCalibration_32V_1A(); // intermediate option 24 | ina219.setCalibration_16V_400mA(); // high precision option 25 | oled.begin(SSD1306_SWITCHCAPVCC, 0x3C); // OLED I2C address 26 | oled.clearDisplay(); // clear OLED display 27 | oled.setTextColor(WHITE); // set font color 28 | oled.setTextSize(1); // set font size (1, 2, 3 or 4) 29 | oled.display(); // update display instructions 30 | } 31 | 32 | void loop() 33 | { 34 | shunt = ina219.getShuntVoltage_mV(); // shunt voltage in mV 35 | load = ina219.getBusVoltage_V(); // load voltage in V 36 | supply = load + shunt / 1000.0; // supply voltage in V 37 | current = ina219.getCurrent_mA(); // current in mA 38 | power = ina219.getPower_mW(); // power in mW 39 | energy = energy + power / 3600.0; // energy in mAh 40 | oled.clearDisplay(); 41 | oled.setCursor(0,0); // display results 42 | oled.print("current ");oled.print(current,0); oled.println(" mA"); 43 | oled.print("shunt ");oled.print(shunt,0); oled.println(" mV"); 44 | oled.print("power ");oled.print(power,0); oled.println(" mW"); 45 | oled.print("energy ");oled.print(energy,0); oled.print(" mAh"); 46 | oled.display(); 47 | delay(5000); 48 | oled.clearDisplay(); 49 | oled.setCursor(0,0); // display supply and load V 50 | oled.print("supply ");oled.print(supply); oled.println(" V"); 51 | oled.print("load ");oled.print(load); oled.println(" V"); 52 | oled.display(); 53 | delay(5000); 54 | } 55 | -------------------------------------------------------------------------------- /Chapter 18/Listing18-9/Listing18-9.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: Inductor meter 3 | * Description: Measure oscillation frequency after voltage pulse 4 | * Created on: October 2020 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 18 - Measuring electricity 8 | ******************************************************************************/ 9 | 10 | #include // Adafruit SSD1306 library 11 | int width = 128; // OLED screen size 12 | int height = 32; // associate oled with SSD1306 13 | Adafruit_SSD1306 oled(width, height, &Wire, -1); 14 | int voltPin = D0; // voltage burst pin 15 | int LM393pin = D3; // LM393 output pin 16 | float capacitor = 1.0; // measured in F 17 | int timeout = 1000; // timeout limit in s 18 | float pulse, pulse1, pulse2, frequency, inductance; 19 | 20 | void setup() 21 | { 22 | pinMode(voltPin, OUTPUT); // define voltPin as output 23 | oled.begin(SSD1306_SWITCHCAPVCC, 0x3C); // OLED I2C address 24 | oled.clearDisplay(); // clear OLED display 25 | oled.setTextColor(WHITE); // set font color 26 | oled.setTextSize(1); // set font size (1, 2, 3 or 4) 27 | oled.display(); // update display instructions 28 | 29 | } 30 | void loop() 31 | { 32 | digitalWrite(voltPin, HIGH); // apply 3.2V on voltPin 33 | delay(5); // time to charge the inductor 34 | digitalWrite(voltPin,LOW); // end of voltage burst 35 | pulse1 = pulseIn(LM393pin, HIGH, timeout); // measure HIGH pulse duration 36 | pulse2 = pulseIn(LM393pin, HIGH, timeout); 37 | if(pulse2 > 0) pulse = (pulse1+pulse2)/2.0; // average pulse length 38 | else pulse = pulse1; 39 | if(pulse > 0) 40 | { 41 | frequency = 1E6/(2.0*pulse); // shorthand for 10 to the power 6 42 | inductance = pulse*pulse/(PI*PI*capacitor); // calculate inductance 43 | oled.clearDisplay(); 44 | oled.setCursor(0,0); // display results 45 | oled.print("inductance uH ");oled.println(inductance,0); 46 | oled.print("frequency Hz ");oled.println(frequency,0); 47 | oled.print("high time us ");oled.print(pulse,0); 48 | oled.display(); 49 | } 50 | delay(1000); 51 | } 52 | -------------------------------------------------------------------------------- /Chapter 19/Listing19-1/Listing19-1.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: Rotary encoder with LEDs 3 | * Description: Control LEDs by rotary encoder rotation direction 4 | * Created on: October 2020 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 19 - Rotary encoder 8 | ******************************************************************************/ 9 | 10 | int CLKpin = D4; // rotary encoder pins 11 | int DTpin = D3; // CLK = pin A and DT = pin B 12 | int redLED = D8; 13 | int greenLED = D7; // define LED pins 14 | int count = 0; 15 | int oldCLK = LOW; 16 | int newCLK; 17 | 18 | void setup() 19 | { 20 | Serial.begin(115200); // define Serial Monitor baud rate 21 | pinMode(redLED, OUTPUT); // set LED pins as output 22 | pinMode(greenLED, OUTPUT); 23 | } 24 | 25 | void loop() 26 | { 27 | newCLK = digitalRead(CLKpin); // state of pin A (CLK) 28 | if(newCLK == LOW && oldCLK == HIGH) // falling edge of pin A 29 | { 30 | if(digitalRead(DTpin) == HIGH) LED(HIGH, 1, "up "); // pin B HIGH 31 | else LED(LOW, -1, "down "); // pin B (DT) LOW 32 | } 33 | oldCLK = newCLK; // reset pin A (CLK) state 34 | // delay(100); // to confirm microcontroller 35 | } // can miss rotary encoder turns 36 | 37 | void LED(int state, int increment, String text) 38 | { 39 | digitalWrite(redLED, 1-state); // turn on or off the LEDs 40 | digitalWrite(greenLED, state); 41 | Serial.print(text); 42 | count = count + increment; // update and display count 43 | Serial.println(count); 44 | } 45 | -------------------------------------------------------------------------------- /Chapter 19/Listing19-2/Listing19-2.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: Rotary encoder with interrupt 3 | * Description: Control LEDs by rotary encoder rotation direction 4 | * Created on: October 2020 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 19 - Rotary encoder 8 | ******************************************************************************/ 9 | 10 | int CLKpin = D4; 11 | int DTpin = D3; 12 | int redLED = D8; 13 | int greenLED = D7; 14 | int count = 0; 15 | volatile int change; // variable used in ISR 16 | 17 | void setup() 18 | { 19 | Serial.begin(115200); 20 | pinMode(redLED, OUTPUT); 21 | pinMode(greenLED, OUTPUT); // attached interrupt 22 | attachInterrupt(digitalPinToInterrupt(CLKpin), isr, FALLING); 23 | } 24 | 25 | void loop() 26 | { 27 | if(change != 0) // rotary encoder direction 28 | { 29 | if(change > 0) LED(HIGH, "up "); // clockwise 30 | else if(change < 0) LED(LOW, "down "); // anti-clockwise 31 | change = 0; 32 | } 33 | } 34 | 35 | void LED(int state, String text) // no change to LED function 36 | { 37 | digitalWrite(redLED, 1-state); 38 | digitalWrite(greenLED, state); 39 | Serial.print(text); 40 | count = count + change; 41 | Serial.println(count); 42 | } 43 | 44 | IRAM_ATTR void isr() // interrupt service routine 45 | { 46 | change = 2*digitalRead(DTpin) - 1; // determine direction of rotation 47 | } 48 | -------------------------------------------------------------------------------- /Chapter 19/Listing19-3/Listing19-3.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: Rotary encoder with square wave states 3 | * Description: Control LEDs by rotary encoder rotation direction 4 | * Created on: October 2020 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 19 - Rotary encoder 8 | ******************************************************************************/ 9 | 10 | int CLKpin = D4; // define rotary encoder pins 11 | int DTpin = D3; 12 | int redLED = D8; // define LED pins 13 | int greenLED = D7; 14 | int vals[] = {0,-1,1,0,1,0,0,-1,-1,0,0,1,0,1,-1,0}; // array of scores 15 | int count = 0; 16 | volatile int score = 0; 17 | volatile int change = 0; // variables used in isr and loop functions 18 | volatile int oldState = 0; 19 | 20 | void setup() 21 | { 22 | Serial.begin(115200); // Serial Monitor baud rate 23 | pinMode(redLED, OUTPUT); // set LED pins as output 24 | pinMode(greenLED, OUTPUT); // attach interrupt 25 | pinMode(CLKpin, INPUT); // required by ESP32 26 | pinMode(DTpin, INPUT); // required by ESP32 27 | attachInterrupt(digitalPinToInterrupt(CLKpin), isr, CHANGE); 28 | attachInterrupt(digitalPinToInterrupt(DTpin), isr, CHANGE); 29 | } 30 | 31 | void loop() 32 | { 33 | if(change != 0) // rotary encoder rotated 34 | { 35 | if(change > 0) LED(HIGH, "up "); // clockwise 36 | else if(change < 0) LED(LOW, "down "); // anti-clockwise 37 | change = 0; 38 | } 39 | } 40 | 41 | void LED(int state, String text) 42 | { 43 | digitalWrite(redLED, 1-state); // turn LEDs on or off 44 | digitalWrite(greenLED, state); 45 | Serial.print(text); 46 | count = count + change; // update count 47 | Serial.println(count); 48 | } 49 | 50 | IRAM_ATTR void isr() // interrupt service routine 51 | { // construct 4-bit number 52 | int newState = (oldState<<2)+(digitalRead(CLKpin)<<1)+digitalRead(DTpin); 53 | score = score + vals[newState]; // allocate score from array 54 | oldState = newState % 4; // remainder to leave new CLK and DT state 55 | if(score == 2 || score == -2) // 2 steps for complete rotation 56 | { 57 | change = score/2; // unit change per two steps 58 | score = 0; // reset score 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /Chapter 19/Listing19-4/Listing19-4.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: Rotary encoder switch 3 | * Description: Categorise length of switch press 4 | * Created on: October 2020 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 19 - Rotary encoder 8 | ******************************************************************************/ 9 | 10 | int SWpin = D2; // rotary encoder switch pin 11 | int SWled = D6; // LED pin 12 | int longPress = 1000; // time (ms) for long or short press 13 | int shortPress = 500; 14 | volatile unsigned long newTime, oldTime; 15 | volatile char changeSW; // variables in loop and isr functions 16 | volatile unsigned int lagTime; 17 | 18 | void setup() 19 | { 20 | Serial.begin(115200); // define Serial Monitor baud rate 21 | pinMode(SWled, OUTPUT); // set LED pin as output 22 | pinMode(SWpin, INPUT_PULLUP); // activate pull-up resistor 23 | attachInterrupt(digitalPinToInterrupt(SWpin), isr, CHANGE); 24 | } // SWpin as interrupt pin and attach isr 25 | 26 | void loop() 27 | { 28 | if(changeSW != ' ') // switch released, turn on or off 29 | { // LED if long or short press 30 | Serial.print(lagTime);Serial.print("\t"); // display switch press time lag 31 | if(changeSW != 'B') digitalWrite(SWled, !digitalRead(SWled)); 32 | if(changeSW == 'L') Serial.println("long press"); 33 | else if(changeSW == 'S') Serial.println("short press"); 34 | else Serial.println("switch bounce"); // display only, no effect on LED 35 | changeSW = ' '; // reset change variable 36 | } 37 | } 38 | 39 | IRAM_ATTR void isr() 40 | { 41 | newTime = millis(); // get time ISR triggered 42 | if(digitalRead(SWpin) == HIGH) // switch now released 43 | { 44 | lagTime = newTime - oldTime; // time between switch presses 45 | if(lagTime > longPress) changeSW = 'L'; // L for long press 46 | else if(lagTime > shortPress) changeSW = 'S'; // S for short press 47 | else changeSW = 'B'; // B for bounce 48 | } 49 | oldTime = newTime; // reset switch press/release time 50 | } 51 | -------------------------------------------------------------------------------- /Chapter 19/Listing19-5/Listing19-5.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: Control incremental count by rotary encoder rotation speed 3 | * Description: Incremental change depends on rotation speed 4 | * Created on: October 2020 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 19 - Rotary encoder 8 | ******************************************************************************/ 9 | 10 | int CLKpin = D4; 11 | int DTpin = D3; 12 | int redLED = D8; 13 | int greenLED = D7; 14 | int vals[] = {0,-1,1,0,1,0,0,-1,-1,0,0,1,0,1,-1,0}; 15 | int count = 0; 16 | volatile int score = 0; volatile int change = 0; 17 | volatile int oldState = 0; 18 | int incLED = D6; // increment indicator LED pin 19 | int rotation = 500; // threshold rotation time (ms) 20 | int increment = 1; // default increment 21 | volatile unsigned long newTime, oldTime, lagTime; 22 | volatile int newCLK; // variables used in ISR 23 | volatile int oldCLK = 0; 24 | 25 | void setup() 26 | { 27 | Serial.begin(115200); 28 | pinMode(redLED, OUTPUT); 29 | pinMode(greenLED, OUTPUT); 30 | pinMode(CLKpin, INPUT); 31 | pinMode(DTpin, INPUT); 32 | attachInterrupt(digitalPinToInterrupt(CLKpin), isr, CHANGE); 33 | attachInterrupt(digitalPinToInterrupt(DTpin), isr, CHANGE); 34 | pinMode(incLED, OUTPUT); // increment indicator LED 35 | } 36 | 37 | void loop() 38 | { 39 | if(change != 0) 40 | { 41 | if(change > 0) LED(HIGH, "up "); 42 | else if(change < 0) LED(LOW, "down "); 43 | change = 0; 44 | } 45 | } 46 | 47 | void LED(int state, String text) 48 | { 49 | digitalWrite(redLED, 1-state); 50 | digitalWrite(greenLED, state); 51 | Serial.print(text); 52 | count = count + change*increment; // incremented count 53 | digitalWrite(incLED, increment>1); // turn LED on, increment = 10 54 | Serial.print(increment);Serial.print("\t"); // display updated increment 55 | Serial.println(count); 56 | } 57 | 58 | IRAM_ATTR void isr() 59 | { // avoid re-reading the square 60 | newCLK = digitalRead(CLKpin); // wave state of pin A (CLK) 61 | int newState = (oldState<<2)+(newCLK<<1)+digitalRead(DTpin); 62 | score = score + vals[newState]; 63 | oldState = newState % 4; 64 | if(score == 2 || score == -2) 65 | { 66 | change = score/2; 67 | score = 0; 68 | } 69 | newTime = millis(); // get time ISR triggered 70 | if(newCLK == HIGH && oldCLK == LOW) // interval between falling 71 | { // and rising edge on pin A (CLK) 72 | lagTime = newTime - oldTime; 73 | if(lagTime < rotation && lagTime > 100) increment = 10; // fast rotation 74 | else if(lagTime > rotation) increment = 1; // slow rotation 75 | oldTime = newTime; // reset rising/falling edge time 76 | } 77 | oldCLK = newCLK; // reset state of pin A (CLK) 78 | } 79 | -------------------------------------------------------------------------------- /Chapter 2/Listing2-2/Listing2-2.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: Camera configuration instructions tab 3 | * Description: Tab containing camera pin numbers and configuration details 4 | * Created on: October 2020 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 2 - Intranet camera 8 | ******************************************************************************/ 9 | 10 | camera_config_t config; // store camera configuration parameters 11 | void configCamera() 12 | { 13 | config.ledc_channel = LEDC_CHANNEL_0; 14 | config.ledc_timer = LEDC_TIMER_0; 15 | config.pin_d0 = 5; 16 | config.pin_d1 = 18; 17 | config.pin_d2 = 19; // GPIO pin numbers 18 | config.pin_d3 = 21; 19 | config.pin_d4 = 36; 20 | config.pin_d5 = 39; 21 | config.pin_d6 = 34; 22 | config.pin_d7 = 35; 23 | config.pin_xclk = 0; 24 | config.pin_pclk = 22; 25 | config.pin_vsync = 25; 26 | config.pin_href = 23; 27 | config.pin_sscb_sda = 26; 28 | config.pin_sscb_scl = 27; 29 | config.pin_pwdn = 32; 30 | config.pin_reset = -1; 31 | config.xclk_freq_hz = 20000000; // clock speed of 20MHz 32 | config.pixel_format = PIXFORMAT_JPEG; // JPEG file format 33 | config.frame_size = FRAMESIZE_SVGA; // SVGA 800600 pixels 34 | config.jpeg_quality = 10; // image quality index 35 | config.fb_count = 1; // frame buffer count 36 | esp_err_t err = esp_camera_init(&config); // initialize camera 37 | if (err != ESP_OK) 38 | { 39 | Serial.print("Camera initialise failed with error"); 40 | Serial.println(err); 41 | return; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /Chapter 2/Listing2-3/Listing2-3.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: Taking a photo and loading to webpage 3 | * Description: Webpage button to take photo and display on webpage 4 | * Created on: October 2020 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 2 - Intranet camera 8 | ******************************************************************************/ 9 | 10 | #include // include esp_camera, 11 | #include // ESPAsyncWebServer libraries 12 | AsyncWebServer server(80); // associate server with library 13 | #include "config_pins.h" // configure instructions tab 14 | #include "buildpage.h" // HTML code for webpage 15 | char ssid[] = "xxxx"; // change xxxx to Wi-Fi ssid 16 | char password[] = "xxxx"; // change xxxx to Wi-Fi password 17 | String pSize; // photo size (bytes) 18 | 19 | void setup() 20 | { 21 | Serial.begin(115200); // define Serial Monitor baud rate 22 | Serial.println("\n\nsettling down for 2s"); // time to settle vibration 23 | delay(2000); 24 | Serial.println("initialising camera, then take photos"); 25 | configCamera(); // function to configure camera 26 | WiFi.begin(ssid, password); // initialise Wi-Fi 27 | while (WiFi.status() != WL_CONNECTED) delay(500); 28 | Serial.print("IP Address: "); 29 | Serial.println(WiFi.localIP()); // display WLAN IP address 30 | server.begin(); // initialise server 31 | server.on("/", HTTP_GET, [](AsyncWebServerRequest * request) 32 | { request->send_P(200, "text/html", page);}); 33 | server.on("/photoURL", HTTP_GET, [](AsyncWebServerRequest * request) 34 | { 35 | camera_fb_t * frame = NULL; 36 | frame = esp_camera_fb_get(); // take photo as JPEG 37 | request->send_P(200, "image/jpeg", // send JPEG image to client 38 | (const uint8_t *)frame->buf, frame->len); 39 | esp_camera_fb_return(frame); // clear photo buffer 40 | pSize = String(frame->len); // display photo size 41 | Serial.print("pSize ");Serial.println(pSize); 42 | }); 43 | } 44 | 45 | void loop() // nothing in loop function 46 | {} 47 | -------------------------------------------------------------------------------- /Chapter 2/Listing2-4/Listing2-4.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: AJAX code for webpage with ESP32-CAM photo 3 | * Description: Webpage code for Listing 2-3 4 | * Created on: October 2020 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 2 - Intranet camera 8 | ******************************************************************************/ 9 | 10 | char page[] PROGMEM = R"( 11 | 12 | ESP32-CAM 13 | 21 | 22 |

ESP32-CAM

23 |
24 | 25 | 26 | 27 |
28 | 29 | 48 | 49 | )"; 50 | -------------------------------------------------------------------------------- /Chapter 2/Listing2-5/Listing2-5.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: Real-time viewing on webpage 3 | * Description: Camera images streamed to webpage, Listing 2-6 required as tab 4 | * Created on: October 2020 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 2 - Intranet camera 8 | ******************************************************************************/ 9 | 10 | #include // include esp http_server, 11 | #include // camera and Wi-Fi libraries 12 | #include 13 | #include "config_pins.h" // configure instructions tab 14 | #include "stream_handler.h" // code to stream images 15 | char ssid[] = "xxxx"; // change xxxx to Wi-Fi ssid 16 | char password[] = "xxxx"; // change xxxx to Wi-Fi password 17 | 18 | void setup() 19 | { 20 | Serial.begin(115200); // define Serial Monitor baud rate 21 | Serial.setDebugOutput(false); // no debug information 22 | WiFi.begin(ssid, password); // initialise Wi-Fi 23 | while (WiFi.status() != WL_CONNECTED) delay(500); 24 | Serial.print("IP Address: "); 25 | Serial.println(WiFi.localIP()); // display WLAN IP address 26 | configCamera(); 27 | sensor_t * s = esp_camera_sensor_get(); // reduce frame size 28 | s->set_framesize(s, FRAMESIZE_VGA); // to 640480 pixels 29 | startCameraServer(); 30 | } 31 | 32 | void startCameraServer() // function to start camera server 33 | { 34 | httpd_handle_t stream_httpd = NULL; 35 | httpd_config_t config = HTTPD_DEFAULT_CONFIG(); 36 | config.server_port = 80; 37 | httpd_uri_t index_uri = {.uri="/", .method=HTTP_GET, 38 | .handler=stream_handler, .user_ctx=NULL}; 39 | if (httpd_start(&stream_httpd, &config) == ESP_OK) 40 | httpd_register_uri_handler(stream_httpd, &index_uri); 41 | } 42 | 43 | void loop() // nothing in loop function 44 | {} 45 | -------------------------------------------------------------------------------- /Chapter 2/Listing2-6/Listing2-6.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: Streaming real-time images 3 | * Description: Tab with code to stream images to webpage, required by Listing 2-5 4 | * Created on: October 2020 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 2 - Intranet camera 8 | ******************************************************************************/ 9 | 10 | #define Boundary "123456789000000000000987654321" 11 | static const char* ContentType = "multipart/x-mixed-replace;boundary=" Boundary; 12 | static const char* StreamBound = "\r\n--" Boundary "\r\n"; 13 | static const char* StreamContent = "Content-Type: image/jpeg\r\nContent-Length: %u\r\n\r\n"; 14 | static esp_err_t stream_handler(httpd_req_t *req) 15 | { 16 | camera_fb_t * frame = NULL; // as in Listing 2-1 17 | uint8_t * jpgBuffer = NULL; // JPEG buffer 18 | size_t jpgLength = 0; // length of JPEG buffer 19 | char * part_buf[64]; 20 | esp_err_t res = ESP_OK; // error status 21 | res = httpd_resp_set_type(req, ContentType); 22 | if (res != ESP_OK) return res; 23 | while (true) 24 | { 25 | frame = esp_camera_fb_get(); // as in Listing 2-1 26 | if (!frame) // as in Listing 2-1 27 | { 28 | Serial.println("Camera capture failed"); // as in Listing 2-1 29 | res = ESP_FAIL; 30 | } 31 | else if (frame->width > 400) 32 | { 33 | jpgLength = frame->len; // set JPEG buffer length 34 | jpgBuffer = frame->buf; // set JPEG buffer 35 | } 36 | if (res == ESP_OK) // no error, stream image 37 | { 38 | size_t hlen = snprintf((char *)part_buf, 64, StreamContent, jpgLength); 39 | res = httpd_resp_send_chunk(req, (const char *)part_buf, hlen); 40 | } 41 | if (res == ESP_OK) res = httpd_resp_send_chunk(req, (const char *)jpgBuffer, jpgLength); 42 | if (res == ESP_OK) res = httpd_resp_send_chunk(req, StreamBound, strlen (StreamBound)); 43 | if (frame) 44 | { 45 | esp_camera_fb_return(frame); // as in Listing 2-1 46 | frame = NULL; 47 | jpgBuffer = NULL; // reset to NULL value 48 | } 49 | else if (jpgBuffer) 50 | { 51 | free(jpgBuffer); // reset to NULL value 52 | jpgBuffer = NULL; 53 | } 54 | if (res != ESP_OK) break; 55 | } 56 | return res; 57 | } 58 | -------------------------------------------------------------------------------- /Chapter 20/Listing20-1/Listing20-1.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: OTA updating 3 | * Description: Update a sketch on a remote microcontroller 4 | * Created on: October 2020 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 20 - OTA and saving data to EEPROM, SPIFFS and Excel 8 | ******************************************************************************/ 9 | 10 | #include // include OTA library 11 | #include // and mDNS libraries 12 | #include // include Wi-FI UDP library 13 | char ssid[] = "xxxx"; // change xxxx to Wi-Fi ssid 14 | char password[] = "xxxx"; // change xxxx to Wi-Fi password 15 | int LEDpin = 2; // built-in LED 16 | 17 | void setup() 18 | { 19 | Serial.begin(115200); // define Serial Monitor baud rate 20 | pinMode(LEDpin, OUTPUT); 21 | WiFi.mode(WIFI_STA); // initialise Wi-Fi 22 | WiFi.begin(ssid, password); 23 | while (WiFi.status() != WL_CONNECTED) 24 | { 25 | delay(500); // flash LED while 26 | flash(); // connecting to Wi-Fi 27 | } 28 | Serial.print("IP address: "); 29 | Serial.println(WiFi.localIP()); // display network port address 30 | ArduinoOTA.setHostname("WeMos2"); // name network port 31 | ArduinoOTA.setPassword("admin1"); // set password 32 | ArduinoOTA.begin(); // initialise ArduinoOTA 33 | } 34 | 35 | void loop() 36 | { 37 | ArduinoOTA.handle(); // check for OTA updates 38 | digitalWrite(LEDpin, !digitalRead(LEDpin)); // turn on or off LED 39 | delay(1000); 40 | } 41 | 42 | void flash() // function to flash LED 43 | { 44 | digitalWrite(LEDpin, HIGH); 45 | delay(100); 46 | digitalWrite(LEDpin, LOW); 47 | } 48 | -------------------------------------------------------------------------------- /Chapter 20/Listing20-3/Listing20-3.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: Write, read and append file with SPIFFS for ESP8266 microcontroller 3 | * Description: Save data on SPIFFS 4 | * Created on: October 2020 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 20 - OTA and saving data to EEPROM, SPIFFS and Excel 8 | ******************************************************************************/ 9 | 10 | #include // include LittleFS library 11 | String filename = "/temp/testfile.txt"; // structure /dir/file 12 | String newname = "/temp/newfile.txt"; 13 | 14 | void setup() 15 | { 16 | Serial.begin(115200); // define Serial Monitor baud rate 17 | if(LittleFS.begin()) Serial.println("initialised OK"); 18 | dirContent("/"); // contents of main directory 19 | dirContent("/temp"); // contents of sub directory 20 | File file = LittleFS.open(filename, "w"); // open file to write 21 | file.println("ABC"); 22 | file.println("123"); // instead of print("xxx\n") 23 | file.close(); 24 | fileContent(filename); // function display file content 25 | dirContent("/temp"); 26 | file = LittleFS.open(filename, "a"); // append to file 27 | file.println("XYZ"); 28 | file.close(); 29 | LittleFS.rename(filename, newname); // change filename not directory 30 | fileContent(newname); 31 | dirContent("/temp"); 32 | if(LittleFS.exists(filename)) LittleFS.remove(filename); // delete file 33 | } 34 | 35 | void dirContent(String dname) // function to display directory content 36 | { 37 | Serial.print(dname);Serial.println(" content"); 38 | Dir dir = LittleFS.openDir(dname); 39 | while(dir.next()) 40 | { 41 | File file = dir.openFile("r"); // read file 42 | Serial.print("file ");Serial.print(file.name());Serial.print("\t"); 43 | Serial.print("size ");Serial.println(file.size()); // filesize 44 | } 45 | } 46 | 47 | void fileContent(String fname) // function to display file content 48 | { 49 | File file = LittleFS.open(fname, "r"); 50 | while(file.available()) Serial.write(file.read()); 51 | file.close(); 52 | } 53 | 54 | void loop() // nothing in loop function 55 | {} 56 | -------------------------------------------------------------------------------- /Chapter 20/Listing20-4/Listing20-4.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: List directory files with SPIFFS for ESP32 microcontroller 3 | * Description: Replace ESP8266 function in Listing 20-3 4 | * Created on: October 2020 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 20 - OTA and saving data to EEPROM, SPIFFS and Excel 8 | ******************************************************************************/ 9 | 10 | void dirContent(String dname) 11 | { 12 | Serial.print(dname);Serial.println(" content"); 13 | File dir = SPIFFS.open(dname); // SPIFFS library 14 | File file = dir.openNextFile(); // openNextFile 15 | while(file) 16 | { 17 | Serial.print("file ");Serial.print(file.name());Serial.print("\t"); 18 | Serial.print("size ");Serial.println(file.size()); 19 | file = dir.openNextFile(); // openNextFile 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Chapter 20/Listing20-5/Listing20-5.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: Downloading SPIFFS data file 3 | * Description: User determines the directory to sore the SPIFFS file 4 | * Created on: October 2020 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 20 - OTA and saving data to EEPROM, SPIFFS and Excel 8 | ******************************************************************************/ 9 | 10 | #include // include LittleFS and 11 | #include // ESPAsyncWebServer libraries 12 | AsyncWebServer server(80); 13 | char ssid[] = "xxxx"; // change xxxx to Wi-Fi ssid 14 | char password[] = "xxxx"; // change xxxx to Wi-Fi password 15 | String filename; // file to be downloaded 16 | 17 | void setup() 18 | { 19 | Serial.begin(115200); // define Serial Monitor baud rate 20 | WiFi.begin(ssid, password); // initialise Wi-Fi 21 | while (WiFi.status() != WL_CONNECTED) delay(500); 22 | Serial.print("IP Address: "); 23 | Serial.println(WiFi.localIP()); // display WLAN IP address 24 | server.begin(); // initialise server 25 | server.on("/download", HTTP_GET, [](AsyncWebServerRequest * request) 26 | { request->send(LittleFS, filename, "text/plain", true); }); 27 | LittleFS.begin(); // initialise SPIFFS 28 | dirContent(""); // contents of main directory 29 | dirContent("temp"); // content of "temp" sub-directory 30 | Serial.println("\nEnter directory/filename to download"); 31 | } 32 | 33 | void loop() 34 | { 35 | if(Serial.available() > 0) // filename entered on Serial Monitor 36 | { 37 | filename = Serial.readString(); // read Serial buffer 38 | Serial.print("In the browser, enter ");Serial.print(WiFi.localIP()); 39 | Serial.print("/download to download file: ");Serial.println(filename); 40 | Serial.println("\n\nEnter directory/filename to download"); 41 | } 42 | } 43 | 44 | void dirContent(String dname) // function to display directory content 45 | { 46 | Serial.print("\nContent of directory: ");Serial.println(dname); 47 | Dir dir = LittleFS.openDir("/"+dname); 48 | while(dir.next()) 49 | { 50 | File file = dir.openFile("r"); // read file 51 | Serial.print(dname);Serial.print("/"); 52 | Serial.print(file.name());Serial.print("\t"); 53 | Serial.print("size ");Serial.println(file.size()); // filesize 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /Chapter 20/Listing20-6/Listing20-6.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: Saving data directly to an Excel file 3 | * Description: MUST BE ABLE TO STOP KEYBOARD 4 | * Created on: October 2020 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 20 - OTA and saving data to EEPROM, SPIFFS and Excel 8 | ******************************************************************************/ 9 | 10 | #include // include Keyboard library 11 | #include // include Unified Sensor library 12 | #include // include BMP280 library 13 | Adafruit_BMP280 bmp; // associate bmp with BMP280 14 | int BMPaddress = 0x76; // I2C address of BMP280 15 | int switchPin = A3; // define switch and LDR pins 16 | int LDRpin = 9; 17 | unsigned long nowTime, lastTime = 0; 18 | float temp, bright; 19 | int counter = 0; 20 | 21 | void setup() 22 | { 23 | Keyboard.begin(); // initialise Keyboard 24 | while(!Keyboard); // delay to setup Keyboard 25 | bmp.begin(BMPaddress); // initialise BMP280 26 | header(); // call header function 27 | } 28 | 29 | void loop() 30 | { // MUST BE ABLE TO STOP KEYBOARD 31 | if(digitalRead(switchPin) == HIGH) // switch to stop Keyboard 32 | { 33 | Keyboard.end(); // stop Keyboard 34 | while(1); // and do nothing else 35 | } 36 | nowTime = millis(); // set start of time interval 37 | if(nowTime - lastTime > 5000) // collect data every 5s 38 | { 39 | counter++; // increment counter 40 | temp = bmp.readTemperature(); // get BMP280 reading 41 | bright = analogRead(LDRpin); // and brightness reading 42 | Keyboard.print(counter); // print counter to Excel 43 | Keyboard.print(char(9)); // print tab character 44 | Keyboard.print(temp); // print temp to Excel 45 | Keyboard.print(char(9)); // print bright to Excel, with 46 | Keyboard.println(bright); // carriage return and new line 47 | lastTime = nowTime; // update start of time interval 48 | } 49 | } 50 | 51 | void header() // function to print columns headers to Excel 52 | { 53 | Keyboard.print("counter"); // print "counter" to Excel 54 | Keyboard.print(char(9)); // print tab character 55 | Keyboard.print("temp"); 56 | Keyboard.print(char(9)); 57 | Keyboard.print("bright"); 58 | Keyboard.print(char(13)); // print carriage return character 59 | Keyboard.print(char(10)); // print new line character 60 | } 61 | -------------------------------------------------------------------------------- /Chapter 21/Listing21-1/Listing21-1.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: Determine first 10k prime numbers 3 | * Description: Sketch used as baseline to measure performance 4 | * Created on: October 2020 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 21 - Microcontrollers 8 | ******************************************************************************/ 9 | 10 | int Nprimes = 9999; // required number of primes - 1 11 | unsigned long number = 2; // start from number 2 12 | int count = 1; // prime number counter 13 | unsigned int start = 0; // store processing time 14 | unsigned long ms; 15 | int chk, limit, mod, divid; 16 | 17 | void setup() 18 | { 19 | Serial.begin(115200); // define Serial Monitor baud rate 20 | while(!Serial); // wait for Pro Micro to connect 21 | Serial.print("\nCPU "); Serial.println(F_CPU/1000000); 22 | start = millis(); // start of processing time 23 | } 24 | 25 | void loop() 26 | { 27 | number++; // increment number to check 28 | chk = is_prime(number); 29 | if (chk > 0) count++; // increment counter when prime 30 | if (count > Nprimes) 31 | { 32 | ms = millis() - start; // display results 33 | Serial.print("Found "); 34 | Serial.print(count); 35 | Serial.print(" primes in "); 36 | Serial.print(ms); 37 | Serial.println(" ms"); 38 | Serial.print("Highest prime is "); 39 | Serial.println(number); 40 | delay(50000); // long delay when finished 41 | } 42 | } 43 | 44 | int is_prime(unsigned long num) // function to check if prime number 45 | { 46 | mod = num % 2; // exclude even numbers 47 | if (mod == 0) return 0; 48 | limit = sqrt(num); // check divisors less than square root 49 | for (int divid = 3; divid <= limit; divid = divid + 2) 50 | { 51 | mod = num % divid; // remainder after dividing 52 | if (mod == 0) return 0; // not prime if zero remainder 53 | } 54 | return 1; // no divisor with zero remainder 55 | } 56 | -------------------------------------------------------------------------------- /Chapter 21/Listing21-2/Listing21-2.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: Microcontroller information 3 | * Description: Display SPI, I2C pin numbers and microcontroller details 4 | * Created on: October 2020 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 21 - Microcontrollers 8 | ******************************************************************************/ 9 | 10 | String str, adjStr; 11 | 12 | void setup() 13 | { 14 | Serial.begin(115200); // Serial Monitor baud rate 15 | Serial.println(); 16 | while(!Serial); // Pro Micro wait for serial port 17 | Serial.print("Arduino IDE version "); 18 | str = String(ARDUINO); // Arduino IDE version 19 | adjStr = str.substring(1,str.length()-5)+"."; 20 | adjStr = adjStr + str.substring(str.length()-4, str.length()-2)+"."; 21 | adjStr = adjStr + str.substring(str.length()-2); 22 | Serial.println(adjStr); // date and time sketch compiled 23 | Serial.print("Compiler version "); Serial.println(__VERSION__); 24 | Serial.print("Compiled date "); Serial.println(__DATE__); 25 | Serial.print("Compiled time "); Serial.println(__TIME__); 26 | Serial.print("Sketch location "); Serial.println(__FILE__); 27 | Serial.print("CPU frequency(MHz) "); // CPU frequency 28 | Serial.println(F_CPU/1000000); 29 | Serial.print("Development board ");Serial.println(ARDUINO_BOARD); 30 | #ifdef __AVR__ // development board 31 | Serial.print("Microcontroller ");Serial.println(ARDUINO_MCU); 32 | #endif // microcontroller 33 | Serial.print("SPI MOSI ");Serial.println(MOSI); // pin layout SPI 34 | Serial.print("SPI MISO ");Serial.println(MISO); 35 | Serial.print("SPI SCK ");Serial.println(SCK); 36 | Serial.print("SPI SS ");Serial.println(SS); 37 | Serial.print("I2C SDA ");Serial.println(SDA); // pin layout I2C 38 | Serial.print("I2C SCL ");Serial.println(SCL); 39 | #ifndef ESP32 40 | Serial.print("LED ");Serial.println(LED_BUILTIN); // built-in LED 41 | #endif 42 | } 43 | 44 | void loop() // nothing in loop function 45 | {} 46 | -------------------------------------------------------------------------------- /Chapter 21/Listing21-3/Listing21-3.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: Controlling Pro Micro LEDs 3 | * Description: Control LEDs directly or with built-in macros 4 | * Created on: October 2020 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 21 - Microcontrollers 8 | ******************************************************************************/ 9 | 10 | int RXLED = 17; // define RXLED pin 11 | //int TXLED = 30; // required if not using macros 12 | 13 | void setup() 14 | {} // nothing in setup function 15 | 16 | void loop() 17 | { 18 | digitalWrite(RXLED, HIGH); // turn off RXLED 19 | // digitalWrite(TXLED, HIGH); // turn off TXLED 20 | TXLED0; // macro to turn off TXLED 21 | delay(1000); 22 | digitalWrite(RXLED, LOW); // turn on RXLED 23 | // digitalWrite(TXLED, LOW); // turn on TXLED 24 | TXLED1; // macro to turn on TXLED 25 | delay(1000); 26 | } 27 | -------------------------------------------------------------------------------- /Chapter 21/Listing21-4/Listing21-4.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: Interrupts with ESP8266 development board 3 | * Description: Difference between interrupts on pins D1-D7 or pin D8 4 | * Created on: October 2020 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 21 - Microcontrollers 8 | ******************************************************************************/ 9 | 10 | int LEDpin = D0; // define LED pin 11 | int switchPin = D7; // define switch pin 12 | volatile int LEDstate = LOW; // initial LED state 13 | // volatile as LEDstate in ISR 14 | void setup() 15 | { 16 | Serial.begin(115200); // define Serial Monitor baud rate 17 | pinMode(LEDpin, OUTPUT); // define LEDpin as OUTPUT 18 | pinMode(switchPin, INPUT_PULLUP); // when switch pin is D1 to D7 19 | attachInterrupt(digitalPinToInterrupt(switchPin), change, FALLING); 20 | // when switch pin is D8 21 | // attachInterrupt(digitalPinToInterrupt(switchPin), change, RISING); 22 | } 23 | 24 | void loop() 25 | { 26 | Serial.println(digitalRead(switchPin)); // display switch pin state 27 | delay(1000); 28 | } 29 | 30 | IRAM_ATTR void change() // interrupt service routine (ISR) 31 | { 32 | LEDstate = 1-LEDstate; // change LED state 33 | digitalWrite(LEDpin, LEDstate); // turn LED on or off 34 | } 35 | -------------------------------------------------------------------------------- /Chapter 21/Listing21-5_NEW/Listing21-5_NEW.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: Analog to digital conversion 3 | * Description: ADC functionality of ESP32 microcontroller 4 | * Created on: October 2020 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 21 - Microcontrollers 8 | ******************************************************************************/ 9 | 10 | int ADCpin = 36; // define ADC pin 11 | 12 | void setup() 13 | { 14 | Serial.begin(115200); // define Serial Monitor baud rate 15 | Serial.println(); 16 | analogSetAttenuation(ADC_11db); // default setting of 11dB 17 | Serial.println(analogRead(ADCpin)); // read ADC pin 18 | analogSetAttenuation(ADC_6db); // change setting to 6dB 19 | Serial.println(analogRead(ADCpin)); 20 | analogSetAttenuation(ADC_2_5db); 21 | Serial.println(analogRead(ADCpin)); 22 | analogSetAttenuation(ADC_0db); 23 | Serial.println(analogRead(ADCpin)); 24 | } 25 | 26 | void loop() 27 | {} // nothing in loop function 28 | -------------------------------------------------------------------------------- /Chapter 21/Listing21-6/Listing21-6.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: PWM signal 3 | * Description: PWM functionality of ESP32 microcontroller 4 | * Created on: October 2020 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 21 - Microcontrollers 8 | ******************************************************************************/ 9 | 10 | int channel = 0; // define PWM output channel 11 | int wavePin = 25; // square wave output pin 12 | int freq = 5000; // square wave frequency 13 | int resolution = 8; // PWM resolution 14 | int bright = 0; 15 | int increm = 5; // increment in duty cycle 16 | int lag = 25; // time between PWM changes 17 | 18 | void setup() 19 | { 20 | pinMode(wavePin, OUTPUT); // square wave pin as output 21 | ledcAttachPin(wavePin, channel); // attached channel to pin 22 | ledcSetup(channel, freq, resolution); 23 | } 24 | 25 | void loop() 26 | { 27 | ledcWrite(channel, bright); // set channel duty cycle 28 | delay(lag); 29 | bright = bright + increm; // increment duty cycle 30 | if(bright <= 0 || bright >= 255) increm = - increm; 31 | } // reverse duty cycle increment 32 | -------------------------------------------------------------------------------- /Chapter 22/Listing22-1/Listing22-1.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: A task on each core 3 | * Description: Allocating tasks to each ESP32 microcontroller core 4 | * Created on: October 2020 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 22 - ESP32 microcontroller features 8 | ******************************************************************************/ 9 | 10 | int redLED = 26; // define LED pins 11 | int blueLED = 27; 12 | TickType_t xOneSec; // create time delay variable 13 | 14 | void setup() 15 | { 16 | Serial.begin(115200); // define Serial Monitor baud rate 17 | pinMode(redLED, OUTPUT); // set LED pins as output 18 | pinMode(blueLED, OUTPUT); 19 | xOneSec = 1000 / portTICK_PERIOD_MS; // define number of ticks 20 | xTaskCreatePinnedToCore(codeRed, "red LED one sec", // allocate tasks to cores 21 | 1000, NULL, 2, NULL, 0); 22 | xTaskCreatePinnedToCore(codeBlue, "blue LED quarter sec", 23 | 1000, NULL, 1, NULL, 1); 24 | } 25 | 26 | void codeRed(void * parameter) // function for red LED 27 | { 28 | for (;;) 29 | { 30 | int tickTime = xTaskGetTickCount(); // tick count at start 31 | digitalWrite(redLED, HIGH); // turn on or off LED 32 | vTaskDelay(xOneSec); // task delay for one second 33 | digitalWrite(redLED, LOW); 34 | vTaskDelay(xOneSec); 35 | int tick = xTaskGetTickCount() - tickTime; // change in tick count 36 | Serial.print("Core ");Serial.print(xPortGetCoreID()); 37 | Serial.print(" red ");Serial.println(tick); 38 | } 39 | } 40 | 41 | void codeBlue(void * parameter) // similar task with 250ms delay 42 | { 43 | for (;;) 44 | { 45 | unsigned long start = millis(); // time at start 46 | digitalWrite(blueLED, HIGH); 47 | delay(250); // task delay of 250ms 48 | digitalWrite(blueLED, LOW); 49 | delay(250); 50 | start = millis() - start; 51 | Serial.print("Core ");Serial.print(xPortGetCoreID()); 52 | Serial.print(" blue ");Serial.println(start); 53 | } 54 | } 55 | 56 | void loop() 57 | { // no instructions in loop function 58 | vTaskDelay(NULL); // other than zero delay 59 | } 60 | -------------------------------------------------------------------------------- /Chapter 22/Listing22-10/Listing22-10.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: Digital to analog conversion 3 | * Description: Generate range of voltages 4 | * Created on: October 2020 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 22 - ESP32 microcontroller features 8 | ******************************************************************************/ 9 | 10 | int DACpin = DAC1; // define DAC pin 11 | 12 | void setup() 13 | {} // nothing in setup function 14 | 15 | void loop() 16 | { 17 | for (int i=0; i<255; i=i+39) 18 | { 19 | dacWrite(DACpin, i); // output voltage 0.5V, 1V... 20 | delay(2000); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Chapter 22/Listing22-11/Listing22-11.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: Capacitive touch sensor 3 | * Description: Touch sensor as a switch 4 | * Created on: October 2020 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 22 - ESP32 microcontroller features 8 | ******************************************************************************/ 9 | 10 | int touchPin = T7; // define touch pin 11 | int LEDpin = 32; // and LED pin 12 | int threshold = 50; // limit for touch pin 13 | volatile unsigned long lastTouch = 0; // time touch pin pressed 14 | 15 | void setup() 16 | { 17 | pinMode(LEDpin, OUTPUT); // LED pin as output 18 | touchAttachInterrupt(touchPin, change, threshold); // define interrupt 19 | } 20 | 21 | void change() // ISR 22 | { 23 | if (millis() - lastTouch < 1000) return; // touch pin recently pressed 24 | lastTouch = millis(); // update touch time 25 | digitalWrite(LEDpin, 1 - digitalRead(LEDpin)); // change LED state 26 | } 27 | 28 | void loop() // nothing in loop function 29 | {} 30 | -------------------------------------------------------------------------------- /Chapter 22/Listing22-12/Listing22-12.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: Hall effect sensor 3 | * Description: Detect magnetic field 4 | * Created on: October 2020 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 22 - ESP32 microcontroller features 8 | ******************************************************************************/ 9 | 10 | int LEDpin = 32; // define LED pin 11 | unsigned long lastHall = 0; // time Hall value changed 12 | 13 | void setup() 14 | { 15 | pinMode(LEDpin, OUTPUT); // LED pin as output 16 | } 17 | 18 | void loop() 19 | { 20 | if(abs(hallRead()) > 30) change(); // call change function 21 | } // when magnetic field detected 22 | 23 | void change() 24 | { 25 | if(millis() - lastHall < 1000) return; // check time last change 26 | lastHall = millis(); // update change time 27 | digitalWrite(LEDpin, 1 - digitalRead(LEDpin)); // change LED state 28 | } 29 | -------------------------------------------------------------------------------- /Chapter 22/Listing22-2/Listing22-2.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: Simultaneous determination of the first 5k and 10k prime numbers 3 | * Description: Allocating tasks to each ESP32 microcontroller core 4 | * Created on: October 2020 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 22 - ESP32 microcontroller features 8 | ******************************************************************************/ 9 | 10 | unsigned long num5k = 2, num10k = 2; // start from number 2 11 | int count5k = 1, count10k = 1; // prime number counters 12 | unsigned int start5k = 0, start10k = 0; // processing times 13 | 14 | void setup() 15 | { 16 | Serial.begin(115200); // define Serial Monitor baud rate 17 | xTaskCreatePinnedToCore(code5k, "5k", 1000, NULL, 1, NULL, 0); 18 | xTaskCreatePinnedToCore(code10k, "10k", 1000, NULL, 1, NULL, 1); 19 | } 20 | 21 | void code5k(void * parameter) // function for 5k primes 22 | { 23 | for (;;) 24 | { 25 | num5k++; // increment number to check 26 | int chk = is_prime(num5k); // call function to test for prime 27 | if (chk > 0) count5k++; // increment counter when prime 28 | if (count5k > 4999) // count up to 5k numbers 29 | { 30 | printLine(start5k, count5k, num5k); // function to display results 31 | num5k = 2; 32 | count5k = 1; // reset parameters 33 | start5k = millis(); 34 | vTaskDelay(1); // delay for watchdog timer 35 | } 36 | } 37 | } 38 | 39 | void code10k(void * parameter) // function for 10k primes 40 | { 41 | for (;;) 42 | { 43 | num10k++; 44 | int chk = is_prime(num10k); 45 | if (chk > 0) count10k++; 46 | if (count10k > 9999) 47 | { 48 | printLine(start10k, count10k, num10k); 49 | num10k = 2; 50 | count10k = 1; 51 | start10k = millis(); 52 | vTaskDelay(1); 53 | } 54 | } 55 | } 56 | 57 | void printLine(unsigned long start, int count, unsigned long number) 58 | { 59 | int ms = millis() - start; 60 | Serial.print("Core ");Serial.print(xPortGetCoreID()); 61 | Serial.print(" Found ");Serial.print(count); 62 | Serial.print(" primes in "); Serial.print(ms); 63 | Serial.print(" ms"); 64 | Serial.print(" highest prime is ");Serial.println(number); 65 | 66 | } 67 | 68 | int is_prime(unsigned long num) // function to check if prime number 69 | { 70 | int mod = num % 2; // exclude even numbers 71 | if (mod == 0) return 0; 72 | int limit = sqrt(num); // check divisors less than square root 73 | for (int divid = 3; divid <= limit; divid = divid + 2) 74 | { 75 | mod = num % divid; // remainder after dividing 76 | if (mod == 0) return 0; // not prime if zero remainder 77 | } 78 | return 1; // no divisor with zero remainder 79 | } 80 | 81 | void loop() 82 | { 83 | vTaskDelay(NULL); 84 | } 85 | -------------------------------------------------------------------------------- /Chapter 22/Listing22-3/Listing22-3.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: Bluetooth communication 3 | * Description: Transmit and receive messages with Bluetooth 4 | * Created on: October 2020 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 22 - ESP32 microcontroller features 8 | ******************************************************************************/ 9 | 10 | #include // include Bluetooth library 11 | BluetoothSerial SerialBT; // associate SerialBT with library 12 | String str; 13 | int strLen; 14 | char c; 15 | 16 | void setup() 17 | { 18 | Serial.begin(115200); // define Serial Monitor baud rate 19 | SerialBT.begin("ESP32 Bluetooth"); // identify Bluetooth device 20 | } 21 | 22 | void loop() 23 | { // received message from Bluetooth device 24 | if(SerialBT.available()) Serial.write(SerialBT.read()); 25 | if(Serial.available()) // message to transmit 26 | { 27 | str = Serial.readString(); // read and display 28 | Serial.print("\t\t\t\t");Serial.println(str); // Serial buffer 29 | strLen = str.length(); 30 | for (int i=0; i // include BLE library 11 | BLEScan * pBLEScan; // pointer to BLE scanner 12 | BLEAddress * pAddress; // and to BLE address 13 | BLEScanResults devices; 14 | String watch = "d5:db:a5:45:99:2f"; // change upper to lower case 15 | String scan; 16 | int scanTime = 3; // scan devices for 3s 17 | int paired = 0, lastPair = 0; 18 | int LEDpin = 25; // define LED pin 19 | 20 | class watchCallback: public BLEAdvertisedDeviceCallbacks 21 | { 22 | void onResult(BLEAdvertisedDevice advertised) // BLE advertising devices 23 | { // option to display device data 24 | // Serial.printf("found device: %s \n", advertised.toString().c_str()); 25 | pAddress = new BLEAddress(advertised.getAddress()); // BLE address 26 | scan = pAddress->toString().c_str(); // convert to string 27 | if(scan == watch) paired = 1; // device matches watch address 28 | } 29 | }; 30 | 31 | void setup() 32 | { 33 | Serial.begin(115200); // define Serial Monitor baud rate 34 | pinMode(LEDpin, OUTPUT); // LED pin as OUTPUT 35 | BLEDevice::init(""); // initialise BLE client 36 | pBLEScan = BLEDevice::getScan(); //create new scan 37 | pBLEScan->setAdvertisedDeviceCallbacks(new watchCallback()); 38 | pBLEScan->setActiveScan(true); 39 | } 40 | 41 | void loop() 42 | { 43 | devices = pBLEScan->start(scanTime, false); // start scanning 44 | // Serial.print("scanned devices ");Serial.print(devices.getCount()); 45 | digitalWrite(LEDpin, paired); // turn on or off LED 46 | if(paired == 0 && lastPair == 1) digitalWrite(LEDpin, 1); 47 | lastPair = paired; // 2 consecutive non-pairings to turn off 48 | paired = 0; // reset paired variable 49 | pBLEScan->clearResults(); // delete scan results 50 | } 51 | -------------------------------------------------------------------------------- /Chapter 22/Listing22-7/Listing22-7.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: Timer control of two independent events 3 | * Description: Simultaneous control of two events 4 | * Created on: October 2020 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 22 - ESP32 microcontroller features 8 | ******************************************************************************/ 9 | 10 | hw_timer_t * timer1 = NULL; // define timer1 11 | portMUX_TYPE timer1Mux = portMUX_INITIALIZER_UNLOCKED; 12 | hw_timer_t * timer2 = NULL; // define timer2 13 | portMUX_TYPE timer2Mux = portMUX_INITIALIZER_UNLOCKED; 14 | int LED1pin = 25; 15 | int LED2pin = 26; // define LED pins 16 | 17 | void setup() 18 | { 19 | Serial.begin(115200); 20 | pinMode(LED1pin, OUTPUT); 21 | pinMode(LED2pin, OUTPUT); 22 | timer1 = timerBegin(1, 80, true); // set timer1 properties 23 | timerAttachInterrupt(timer1, &timer1ISR, true); 24 | timerAlarmWrite(timer1, 250000, true); // interval of 0.25s 25 | timerAlarmEnable(timer1); 26 | timer2 = timerBegin(2, 80, true); // set timer2 properties 27 | timerAttachInterrupt(timer2, &timer2ISR, true); 28 | timerAlarmWrite(timer2, 1000000, true); // interval of 1s 29 | timerAlarmEnable(timer2); 30 | } 31 | 32 | void loop() 33 | { 34 | vTaskDelay(NULL); 35 | } 36 | 37 | IRAM_ATTR void timer1ISR() // ISR for timer1 38 | { 39 | portENTER_CRITICAL_ISR(&timer1Mux); 40 | digitalWrite(LED1pin, !digitalRead(LED1pin)); 41 | portEXIT_CRITICAL_ISR(&timer1Mux); 42 | } 43 | 44 | IRAM_ATTR void timer2ISR() // ISR for timer 2 45 | { 46 | portENTER_CRITICAL_ISR(&timer2Mux); 47 | digitalWrite(LED2pin, !digitalRead(LED2pin)); 48 | portEXIT_CRITICAL_ISR(&timer2Mux); 49 | } 50 | -------------------------------------------------------------------------------- /Chapter 22/Listing22-8/Listing22-8.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: RTC and sleep mode 3 | * Description: Activate ESP32 microcontroller from sleep mode with switch 4 | * Created on: October 2020 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 22 - ESP32 microcontroller features 8 | ******************************************************************************/ 9 | 10 | #include // include rtc input-output library 11 | int switchPin = 32; // define switch pin 12 | int LEDpin = 26; // and LED pin 13 | int builtinLED = 2; 14 | 15 | void setup() 16 | { 17 | Serial.begin(115200); // define Serial Monitor baud rate 18 | pinMode(LEDpin, OUTPUT); // LED pins as output 19 | pinMode(builtinLED, OUTPUT); 20 | flash(); // call flash function 21 | rtc_gpio_pullup_en((gpio_num_t)switchPin); // pull-up switch pin 22 | esp_sleep_enable_ext0_wakeup((gpio_num_t)switchPin, 0); 23 | } // wakeup on switch pin with state 0 24 | 25 | void loop() 26 | { 27 | Serial.print("sleep mode on pin ");Serial.println(switchPin); 28 | esp_deep_sleep_start(); // ESP32 in sleep mode 29 | } 30 | 31 | void flash() 32 | { 33 | for (int i=0; i<3; i++) // flash LEDs three times 34 | { 35 | digitalWrite(LEDpin, HIGH); // LED on pin 36 | digitalWrite(builtinLED, HIGH); // and built-in LED 37 | delay(200); 38 | digitalWrite(LEDpin, LOW); 39 | digitalWrite(builtinLED, LOW); 40 | delay(100); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Chapter 22/Listing22-9/Listing22-9.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: RTC timer and sleep mode 3 | * Description: Activate ESP32 microcontroller from sleep mode after time interval 4 | * Created on: October 2020 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 22 - ESP32 microcontroller features 8 | ******************************************************************************/ 9 | 10 | RTC_DATA_ATTR int count = 0; // store count in RTC memory 11 | unsigned long micro = 5000000; // time interval in s 12 | 13 | void setup() 14 | { 15 | Serial.begin(115200); // define Serial Monitor baud rate 16 | esp_sleep_enable_timer_wakeup(micro); // RTC timer interval in s 17 | } 18 | 19 | void loop() 20 | { 21 | count++; // increment and print count 22 | Serial.print("count ");Serial.println(count); 23 | esp_deep_sleep_start(); // microcontroller in sleep mode 24 | } 25 | -------------------------------------------------------------------------------- /Chapter 22/Table_22-1_left-side/Table_22-1_left-side.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: Semaphore method 3 | * Description: Allocating tasks to each ESP32 microcontroller core 4 | * Created on: October 2020 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 22 - ESP32 microcontroller features 8 | ******************************************************************************/ 9 | 10 | int redLED = 26; 11 | int blueLED= 27; 12 | SemaphoreHandle_t baton; 13 | volatile int redOff; 14 | 15 | void setup() 16 | { 17 | pinMode(redLED, OUTPUT); 18 | pinMode(blueLED, OUTPUT); 19 | xTaskCreatePinnedToCore(codeRed, "red LED ", 1000, NULL, 1, NULL, 0); 20 | xTaskCreatePinnedToCore(codeBlu, "blue LED", 1000, NULL, 1, NULL, 1); 21 | baton = xSemaphoreCreateMutex(); 22 | } 23 | 24 | void codeRed(void * parameter) 25 | { 26 | for (;;) 27 | { 28 | redOff = random(500, 2000); 29 | delay(1); 30 | xSemaphoreGive(baton); 31 | digitalWrite(redLED, HIGH); 32 | delay(1000); 33 | digitalWrite(redLED, LOW); 34 | delay(redOff); 35 | } 36 | } 37 | 38 | void codeBlu(void * parameter) 39 | { 40 | for (;;) 41 | { 42 | xSemaphoreTake(baton, portMAX_DELAY); 43 | digitalWrite(blueLED, HIGH); 44 | delay(redOff); 45 | digitalWrite(blueLED, LOW); 46 | } 47 | } 48 | 49 | void loop() 50 | { 51 | vTaskDelay(NULL); 52 | } 53 | -------------------------------------------------------------------------------- /Chapter 22/Table_22-1_right-side/Table_22-1_right-side.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: Queue method 3 | * Description: Allocating tasks to each ESP32 microcontroller core 4 | * Created on: October 2020 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 22 - ESP32 microcontroller features 8 | ******************************************************************************/ 9 | 10 | int redLED = 26; 11 | int blueLED = 27; 12 | QueueHandle_t queue; 13 | 14 | void setup() 15 | { 16 | pinMode(redLED, OUTPUT); 17 | pinMode(blueLED, OUTPUT); 18 | xTaskCreatePinnedToCore(codeRed, "red LED ", 1000, NULL, 1, NULL, 0); 19 | xTaskCreatePinnedToCore(codeBlue, "blue LED", 1000, NULL, 1, NULL, 1); 20 | queue = xQueueCreate(1, sizeof(int)); 21 | } 22 | 23 | void codeRed(void * parameter) 24 | { 25 | for (;;) 26 | { 27 | int redOff = random(500, 2000); 28 | delay(1); 29 | xQueueSend(queue, &redOff, portMAX_DELAY); 30 | digitalWrite(redLED, HIGH); 31 | delay(1000); 32 | digitalWrite(redLED, LOW); 33 | delay(redOff); 34 | } 35 | } 36 | 37 | void codeBlue(void * parameter) 38 | { 39 | for (;;) 40 | { 41 | int blueOn; 42 | xQueueReceive(queue, &blueOn, portMAX_DELAY); 43 | digitalWrite(blueLED, HIGH); 44 | delay(blueOn); 45 | digitalWrite(blueLED, LOW); 46 | } 47 | } 48 | void loop() 49 | { 50 | vTaskDelay(NULL); 51 | } 52 | -------------------------------------------------------------------------------- /Chapter 3/Listing3-1/Listing3-1.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: Display text and shapes 3 | * Description: Demonstration of displaying text and images on screen 4 | * Created on: October 2020 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 3 - International weather station 8 | ******************************************************************************/ 9 | 10 | #include // include ILI9341 library 11 | int tftCS = D8; // screen chip select pin 12 | int tftDC = D4; // data command select pin 13 | int tftRST = D0; // reset pin 14 | // associate tft with ILI9341 lib 15 | Adafruit_ILI9341 tft = Adafruit_ILI9341(tftCS, tftDC, tftRST); 16 | String texts[] = // color names 17 | {"BLUE","RED","GREEN","CYAN","MAGENTA","YELLOW","WHITE","GREY"}; 18 | unsigned int colors[ ] = // color codes 19 | {ILI9341_BLUE, ILI9341_RED, ILI9341_GREEN, ILI9341_CYAN, 20 | ILI9341_MAGENTA, ILI9341_YELLOW, ILI9341_WHITE, ILI9341_LIGHTGREY}; 21 | String text; 22 | unsigned int color, chkTime; 23 | 24 | void setup() 25 | { 26 | tft.begin(); // initialise screen 27 | tft.setRotation(2); // portrait, connections at top 28 | tft.fillScreen(ILI9341_BLACK); // fill screen in black 29 | tft.drawRect(0,0,239,319,ILI9341_WHITE); // draw white frame line 30 | tft.drawRect(1,1,237,317,ILI9341_WHITE); // and second frame line 31 | tft.setTextSize(4); // set text size 32 | } 33 | 34 | void loop() 35 | { 36 | tft.fillRect(2,2,235,314,ILI9341_BLACK); // clear screen apart from frame 37 | for (int i=0; i<8; i++) // for each color 38 | { 39 | color = colors[i]; // set color 40 | text = texts[i]; // set text for color 41 | tft.setTextColor(color); // set text color 42 | tft.setCursor(20,40*i+2); // position cursor 43 | tft.print(text); // print color text (name) 44 | delay(250); // delay 250ms between colors 45 | } 46 | for (int i=0; i<8; i++) // for each color 47 | { 48 | color = colors[i]; 49 | text = texts[i]; 50 | tft.fillRect(2,2,235,314,ILI9341_BLACK); 51 | tft.setCursor(20,25); // cursor to position (20, 25) 52 | tft.setTextColor(color); 53 | tft.print(text); // draw filled-in triangle 54 | if ((i+1) % 3 == 0) tft.fillTriangle(20,134,64,55,107,134,color); 55 | // draw open rectangle 56 | else if ((i+1) % 2 == 0) tft.drawRect(20,55,88,80,color); 57 | else tft.fillCircle(64,95,39,color); // draw filled-in circle 58 | delay(250); 59 | } 60 | tft.fillRect(2,2,235,314,ILI9341_BLACK); 61 | tft.drawLine(2,158,236,158,ILI9341_RED); // draw horizontal RED line 62 | delay(250); 63 | } 64 | -------------------------------------------------------------------------------- /Chapter 3/Listing3-2/Listing3-2.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: Pin definitions for ESP8266 and ESP32 development boards 3 | * Description: Code included at start of sketch for ESP8266 and ESP32 4 | * Created on: October 2020 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 3 - International weather station 8 | ******************************************************************************/ 9 | 10 | #ifdef ESP32 11 | int tftCS = 5; // screen chip select pin 12 | int tftDC = 26; // data command select pin 13 | int tftRST = 25; // reset pin 14 | #elif ESP8266 15 | int tftCS = D8; 16 | int tftDC = D4; 17 | int tftRST = D0; 18 | #else // Arduino IDE error message 19 | #error "ESP8266 or ESP32 microcontroller only" 20 | #endif 21 | -------------------------------------------------------------------------------- /Chapter 3/Listing3-3/Listing3-3.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: TFT-eSPI library User_Setup settings for ESP8266 and ESP32 development boards 3 | * Description: Pin numbers for ESP8266 or ESP32 - required by TFT-eSPI library 4 | * Created on: October 2020 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 3 - International weather station 8 | ******************************************************************************/ 9 | 10 | #define TFT_CS PIN_D8 // ESP8266 SPI and touch screen 11 | #define TFT_DC PIN_D4 12 | #define TFT_RST PIN_D0 13 | #define TOUCH_CS PIN_D1 14 | 15 | /* // lines between /* and */ are commented out 16 | #define TFT_MISO 19 // ESP32 SPI and touch screen 17 | #define TFT_MOSI 23 18 | #define TFT_SCLK 18 19 | #define TFT_CS 5 20 | #define TFT_DC 26 21 | #define TFT_RST 25 22 | #define TOUCH_CS 27 23 | */ 24 | 25 | #define ILI9341_DRIVER // ILI9341 SPI TFT LCD screen 26 | #define TFT_RGB_ORDER TFT_BGR // color order Blue-Green-Red 27 | #define LOAD_GLCD // font 1: Adafruit 8-pixel high 28 | #define LOAD_FONT2 // font 2: small 16-pixel high 29 | #define LOAD_FONT4 // font 4: medium 26-pixel high 30 | #define SPI_FREQUENCY 40000000 // SPI 40MHz 31 | #define SPI_READ_FREQUENCY 20000000 // SPI read 20MHz 32 | #define SPI_TOUCH_FREQUENCY 2500000 // SPI touch 2.5MHz 33 | -------------------------------------------------------------------------------- /Chapter 3/Listing3-4/Listing3-4.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: Calibration of ILI9341 SPI TFT LCD screen 3 | * Description: Touch screen calibration when using TFT-eSPI library 4 | * Created on: October 2020 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 3 - International weather station 8 | ******************************************************************************/ 9 | 10 | #include // include TFT_eSPI library 11 | TFT_eSPI tft = TFT_eSPI(); // associate tft with TFT-eSPI lib 12 | uint16_t calData[5]; // calibration parameters 13 | String str; 14 | 15 | void setup() 16 | { 17 | tft.init(); // initialise ILI9341 TFT screen 18 | tft.setRotation(1); // landscape, connections on right 19 | tft.setTextFont(1); // set text font and size 20 | tft.setTextSize(1); 21 | calibrate(); // call calibration function 22 | } 23 | 24 | void calibrate() // function to calibrate ILI9341 TFT screen 25 | { 26 | tft.fillScreen(TFT_BLACK); // fill screen in black 27 | tft.setTextColor(TFT_WHITE, TFT_BLACK); // set text color, white on black 28 | tft.setCursor(30, 0); // move cursor to position (0, 30) 29 | tft.println("Touch corners as indicated"); 30 | tft.calibrateTouch(calData, TFT_RED, TFT_BLACK, 15); // calibrate screen 31 | tft.fillScreen(TFT_BLACK); 32 | tft.setCursor(0, 50); 33 | tft.setTextSize(2); 34 | tft.print("Calibration parameters"); 35 | str = ""; // display calibration parameters 36 | for (int i=0; i<4; i++) str = str + String(calData[i])+","; 37 | str = str + String(calData[4]); 38 | tft.setCursor(0, 90); 39 | tft.print(str); 40 | } 41 | void loop() // nothing in loop function 42 | {} 43 | -------------------------------------------------------------------------------- /Chapter 3/Listing3-5/Listing3-5.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: Paintpot with TFT-eSPI library 3 | * Description: "Painting" on touch screen - use your calibration parameters 4 | * Created on: October 2020 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 3 - International weather station 8 | ******************************************************************************/ 9 | 10 | #include // include TFT-eSPI library 11 | TFT_eSPI tft = TFT_eSPI(); // associate tft with TFT-eSPI lib 12 | uint16_t calData[] = {450, 3400, 390, 3320, 3}; // calibration parameters 13 | uint16_t x = 0, y = 0; 14 | int radius = 2; // define paintbrush radius 15 | unsigned int color; 16 | 17 | void setup() 18 | { 19 | tft.init(); // initialise ILI9341 TFT screen 20 | tft.setRotation(1); // landscape, connections on right 21 | tft.setTouch(calData); // include calibration parameters 22 | clear(); // call function to reset screen 23 | } 24 | 25 | void loop() 26 | { 27 | if (tft.getTouch(&x, &y)>0) // if screen pressed 28 | { 29 | if(x>20) tft.fillCircle(x, y, radius, color); // draw point 30 | if(x>0 && x<20) // select color from color palette 31 | { 32 | if(y>75 && y<95) color = TFT_RED; 33 | else if(y>100 && y<120) color = TFT_YELLOW; 34 | else if(y>125 && y<145) color = TFT_GREEN; 35 | else if(y>150 && y<170) color = TFT_BLUE; 36 | else if(y>175 && y<195) color = TFT_WHITE; 37 | // display selected color 38 | if(y>75 && y<195) tft.fillCircle(10, 50, 10, color); 39 | else if(y>215) clear(); // clear screen 40 | } 41 | } 42 | } 43 | 44 | void clear() // function to reset screen 45 | 46 | { 47 | tft.fillScreen(TFT_BLACK); // fill screen 48 | tft.setTextColor(TFT_GREEN); // set text color 49 | tft.setTextSize(2); // set text size 50 | tft.setCursor(110,5); // position cursor 51 | tft.print("Paintpot"); // screen title 52 | tft.fillRect(0,75,20,20, TFT_RED); 53 | tft.fillRect(0,100,20,20,TFT_YELLOW); 54 | tft.fillRect(0,125,20,20,TFT_GREEN); // build color palette 55 | tft.fillRect(0,150,20,20, TFT_BLUE); 56 | tft.fillRect(0,175,20,20, TFT_WHITE); 57 | tft.drawCircle(10,225,10, TFT_WHITE); // select to clear screen 58 | tft.setCursor(25,217); 59 | tft.setTextColor(TFT_WHITE); 60 | tft.print("clear"); 61 | color = TFT_WHITE; 62 | } 63 | -------------------------------------------------------------------------------- /Chapter 4/Listing4-1/Listing4-1.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: Sweeping colors along an RGB LED strip 3 | * Description: Demonstration of controlling a WS2812 RGB LED strip 4 | * Created on: October 2020 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 4 - Internet clock 8 | ******************************************************************************/ 9 | 10 | #include // include Adafruit NeoPixel library 11 | int LEDpin = D1; // define data pin 12 | int LEDnumber = 30; // number of LEDS in strip 13 | // associate strip with NeoPixel library 14 | Adafruit_NeoPixel strip(LEDnumber, LEDpin, NEO_GRB + NEO_KHZ800); 15 | // color white,red,lime,blue,yellow,cyan,magenta,grey,maroon,olive,green,purple,teal,navy 16 | int R[ ] = {255,255, 0, 0,255, 0,255,128,128,128, 0,128, 0, 0}; 17 | int G[ ] = {255, 0,255, 0,255,255, 0,128, 0,128,128, 0,128, 0}; 18 | int B[ ] = {255, 0, 0,255, 0,255,255,128, 0, 0, 0,128,128,128}; 19 | uint32_t color; // color is 32-bit or unsigned long 20 | 21 | void setup() 22 | { 23 | strip.begin(); // initialise LED strip 24 | strip.setBrightness(10); // define LED brightness (1 to 255) 25 | strip.show(); // sets all pixels to "off" as no color set 26 | } 27 | 28 | void loop() 29 | { 30 | for (int i=0; i<14; i++) // cycle through the RGB colors 31 | { 32 | color = strip.Color(R[i],G[i],B[i]); // convert RGB values to 32-bit number 33 | sweep(color, 40); // sweep color through the LED strip 34 | } 35 | rainbow(3, 10); // rainbow colors for three cycles 36 | } // with a 10ms time lag for each color 37 | 38 | void sweep(uint32_t color, int lag) // color sweep function 39 | { 40 | for (int i=0; istrandtest 50 | { 51 | for (long Pixel1Hue = 0; Pixel1Hue < cycle*65536; Pixel1Hue += 256) 52 | { 53 | for (int i=0; i // include IRutils library 11 | int IRpin = D1; // IR receiver pin 12 | int BufferSize = 1024; // longer signal length 13 | int Timeout = 50; // block repeat signals 14 | IRrecv irrecv(IRpin, BufferSize, Timeout, true); 15 | decode_results reading; // IRremote reading 16 | 17 | void setup() 18 | { 19 | Serial.begin(115200); // define Serial Monitor baud rate 20 | irrecv.enableIRIn(); // initialise the IR receiver 21 | } 22 | 23 | void loop() 24 | { 25 | if (irrecv.decode(&reading)) // read pulsed signal 26 | Serial.print(resultToHumanReadableBasic(&reading)); 27 | } // display signal information 28 | -------------------------------------------------------------------------------- /Chapter 5/Listing5-3/Listing5-3.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: Decoding infrared signals with an ESP32 development board 3 | * Description: Decode IR signals for controlling MP3 player in Listing 5-4 4 | * Created on: October 2020 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 5 - MP3 player 8 | ******************************************************************************/ 9 | 10 | #include // include IRremote library version 2.8.0 11 | int IRpin = 23; // IR receiver pin 12 | IRrecv irrecv(IRpin); 13 | decode_results reading; 14 | 15 | void setup() 16 | { 17 | Serial.begin(115200); 18 | irrecv.enableIRIn(); 19 | } 20 | 21 | void loop() 22 | { 23 | if (irrecv.decode(&reading)) 24 | { 25 | if(reading.decode_type == NEC) Serial.print("NEC: "); 26 | else if(reading.decode_type == SONY) Serial.print("Sony: "); 27 | else Serial.print("Other: "); 28 | Serial.print(reading.value, HEX); 29 | Serial.print("\tBits: "); // display signal HEX code 30 | Serial.println(reading.bits); // and bit number 31 | delay(200); // delay before next IR signal 32 | irrecv.resume(); // receive the next value 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Chapter 5/Listing5-3_NEW/Listing5-3_NEW.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: Decoding infrared signals with an ESP32 development board 3 | * Description: Decode IR signals for controlling MP3 player in Listing 5-4 4 | * Created on: February 2021 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 5 - MP3 player 8 | ******************************************************************************/ 9 | #include // include IRremote library version 3.0.2 10 | int IRpin = 21; // IR receiver pin 11 | String prot[] = {"UNKNOWN","DENON","DISH","JVC","LG","NEC","PANASONIC","KASEIKYO", 12 | "KASEIKYO_JVC","KASEIKYO_DENON","KASEIKYO_SHARP","KASEIKYO_MITSUBISHI", 13 | "RC5","RC6","SAMSUNG","SHARP","SONY","APPLE","BOSEWAVE","LEGO_PF", 14 | "MAGIQUEST","WHYNTER"}; // from irProtocol.h 15 | void setup() 16 | { 17 | Serial.begin(115200); 18 | IrReceiver.begin(IRpin); 19 | } 20 | 21 | void loop() 22 | { 23 | if(IrReceiver.decode()) 24 | { 25 | IrReceiver.printIRResultMinimal(&Serial);// two signal summaries 26 | if(IrReceiver.decodedIRData.protocol != 0) Serial.println(); 27 | IrReceiver.printIRResultShort(&Serial); 28 | Serial.print(prot[IrReceiver.decodedIRData.protocol]); // display protocol, 29 | Serial.print("\t0x"); 30 | if(IrReceiver.decodedIRData.protocol == 0) Serial.print(IrReceiver.decodedIRData.decodedRawData, HEX); 31 | else Serial.print(IrReceiver.decodedIRData.command, HEX); // signal HEX code 32 | Serial.print("\tBits ");Serial.println(IrReceiver.decodedIRData.numberOfBits); // and bit number 33 | delay(200); // delay before next IR signal 34 | IrReceiver.resume(); // receive the next value 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /Chapter 5/Listing5-4/Listing5-4.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: Infrared remote control of MP3 player 3 | * Description: Revised loop function from Listing 5-1 4 | * Created on: October 2020 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 5 - MP3 player 8 | ******************************************************************************/ 9 | 10 | void loop() 11 | { 12 | if(finish == 1) // current audio file ended 13 | { 14 | cmd(0x01, 0); // play next track 15 | finish = 0; // set finish variable 16 | cmd(0x4C, 0); // get track number 17 | } 18 | if(irrecv.decode(&reading)) // read pulsed signal 19 | { 20 | if(reading.value == 0x8D1) // next audio file is selected 21 | { 22 | file = file+1; // increment file name 23 | if(file > fileMax) file = fileMin; // constrain file name < fileMax 24 | cmd(0x12, file); // play next audio file 25 | finish = 0; // set finish variable 26 | cmd(0x4C, 0); // get track number 27 | } 28 | else if(reading.value == 0x491) // increase volume is selected 29 | { 30 | cmd(0x04, 0); // increase volume 31 | cmd(0x43, 0); // get volume value 32 | } 33 | else if(reading.value == 0xC91) // decrease volume is selected 34 | { 35 | cmd(0x05, 0); // decrease volume 36 | cmd(0x43, 0); // get volume value 37 | } 38 | else if(reading.value == 0x1D1) // change equaliser is selected 39 | { 40 | EQstate = EQstate+1; // increment equaliser 41 | if(EQstate > 5) EQstate = 0; // constrain equaliser value 42 | Serial.println(EQ[EQstate]); 43 | cmd(0x07, EQstate); // change equaliser setting 44 | } 45 | else 46 | { 47 | switch(reading.value) // switch case for selected track 48 | { 49 | case 0x011: track = 1; break; 50 | case 0x811: track = 2; break; 51 | case 0x411: track = 3; break; // map remote signal to play track 52 | case 0xC11: track = 4; break; 53 | case 0x211: track = 5; break; 54 | } 55 | cmd(0x03, track); // play track 56 | finish = 0; // set finish variable 57 | cmd(0x4C, 0); // get track number 58 | } 59 | // irrecv.resume(); // for ESP32, receive next value 60 | } 61 | delay(100); 62 | } 63 | -------------------------------------------------------------------------------- /Chapter 5/Listing5-6/Listing5-6.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: MP3 player alarm - short version 3 | * Description: Sound recoding on MP3 player triggered by PIR 4 | * Created on: October 2020 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 5 - MP3 player 8 | ******************************************************************************/ 9 | 10 | #include // include SoftwareSerial library 11 | SoftwareSerial SoftSer(D6, D7); // define SoftSer TX pin 12 | int PIRpin = D2; // PIR sensor and LED pins 13 | int LEDpin = D3; 14 | byte serialCom[10] = {0x7E,0xFF,0x06,0x12,0x00,0x00,0x03,0xFE,0xE6,0xEF}; 15 | // one control command 16 | void setup() 17 | { 18 | SoftSer.begin(9600); // software Serial baud rate 19 | pinMode(LEDpin, OUTPUT); // LED pin as OUTPUT 20 | } 21 | 22 | void loop() 23 | { 24 | if(digitalRead(PIRpin) == HIGH) // PIR sensor triggered 25 | { 26 | digitalWrite(LEDpin, HIGH); // turn on LED and play sound 27 | for(int i=0; i<10; i++) SoftSer.write(serialCom[i]); 28 | delay(10000); 29 | digitalWrite(LEDpin, LOW); // turn off LED after 10s 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Chapter 5/Listing5-8/Listing5-8.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: ISD1820 record and playback module 3 | * Description: Recording and playback of sounds 4 | * Created on: October 2020 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 5 - MP3 player 8 | ******************************************************************************/ 9 | 10 | int playPin = D3; // define playback pin 11 | int recPin = D4; // define record pin 12 | char data; 13 | 14 | void setup() 15 | { 16 | Serial.begin(115200); // define Serial Monitor baud rate 17 | Serial.println("Enter r to record (10 seconds) or p to playback"); 18 | digitalWrite(playPin, LOW); // avoid playPin going HIGH 19 | pinMode(playPin, OUTPUT); // define playPin and recPin 20 | pinMode(recPin, OUTPUT); // as OUTPUT 21 | } 22 | 23 | void loop() 24 | { 25 | while(Serial.available() > 0) // if data available in Serial buffer 26 | { 27 | data = Serial.read(); // read Serial buffer 28 | if(data == 'r') 29 | { 30 | Serial.println("recording while light is on"); 31 | digitalWrite(recPin, HIGH); // HIGH to activate recording 32 | delay(10000); // recording time of 10s 33 | digitalWrite(recPin, LOW); // reset to LOW signal 34 | } 35 | else if(data == 'p') 36 | { 37 | Serial.println("playback"); 38 | digitalWrite(playPin, HIGH); // HIGH to activate playback 39 | delay(10); // short delay of 10ms 40 | digitalWrite(playPin, LOW); // reset to LOW signal 41 | } 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /Chapter 7/Listing7-1/Listing7-1.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: WLAN and LED functions 3 | * Description: Control two LEDs with buttons on webpage 4 | * Created on: October 2020 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 7 - Wireless local area network 8 | ******************************************************************************/ 9 | 10 | #include // include ESP8266webserver lib 11 | ESP8266WebServer server; // associate server with library 12 | char ssidAP[] = "ESP8266"; // WLAN SSID and password 13 | char passwordAP[] = "12345678"; 14 | IPAddress local_ip(192,168,2,1); // pre-defined IP address values 15 | IPAddress gateway(192,168,2,1); 16 | IPAddress subnet(255,255,255,0); 17 | #include "buildpage.h" // webpage HTML code 18 | int LEDGpin = D7; // define LED pins 19 | int LEDRpin = D8; 20 | int LEDR = LOW; // default LED states 21 | int LEDG = LOW; 22 | int counter = 0; 23 | 24 | void setup() 25 | { 26 | WiFi.mode(WIFI_AP); // Wi-Fi AP mode 27 | delay(1000); // setup AP mode 28 | WiFi.softAPConfig(local_ip, gateway, subnet); // predefined IP address 29 | WiFi.softAP(ssidAP, passwordAP); // initialise Wi-Fi 30 | server.begin(); // initialise server 31 | server.on("/", base); // load default webpage 32 | server.on("/LEDGurl", LEDGfunct); // map URLs to functions: 33 | server.on("/LEDRurl", LEDRfunct); // LEDGfunct, LEDRfunct 34 | server.on("/zeroUrl", zeroFunct); // and zeroFunct 35 | pinMode(LEDGpin, OUTPUT); // define LED pins as output 36 | pinMode(LEDRpin, OUTPUT); 37 | } 38 | 39 | void base() // function to load default webpage 40 | { // and send HTML code to client 41 | server.send(200, "text.html", webcode(LEDG, LEDR, counter)); 42 | } 43 | 44 | void LEDGfunct() // function to change green LED state, 45 | { // increment counter and 46 | LEDG = !LEDG; // send HTML code to client 47 | digitalWrite(LEDGpin, LEDG); 48 | counter++; 49 | server.send(200, "text/html", webcode(LEDG, LEDR, counter)); 50 | } 51 | 52 | void LEDRfunct() // function to change red LED state, 53 | { // increment counter and 54 | LEDR = !LEDR; // send HTML code to client 55 | digitalWrite(LEDRpin, LEDR); 56 | counter++; 57 | server.send(200, "text/html", webcode(LEDG, LEDR, counter)); 58 | } 59 | 60 | void zeroFunct() // function to zero counter 61 | { // and send HTML code to client 62 | counter = 0; 63 | server.send(200, "text/html", webcode(LEDG, LEDR, counter)); 64 | } 65 | 66 | void loop() 67 | { 68 | server.handleClient(); // manage HTTP requests 69 | } 70 | -------------------------------------------------------------------------------- /Chapter 7/Listing7-1/buildpage.h: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: HTML code for WLAN webpage 3 | * Description: Webpage code for Listing 7-1 4 | * Created on: October 2020 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 7 - Wireless local area network 8 | ******************************************************************************/ 9 | 10 | String webcode(int LEDG, int LEDR, int counter) 11 | { 12 | String page = ""; 13 | page +="Local network"; 14 | page +=""; 25 | page +=""; 26 | page +="

ESP8266 local area network

"; 27 | page +=""; 28 | if(LEDG>0) 29 | { 30 | page +=""; 32 | } 33 | else 34 | { 35 | page +=""; 37 | } 38 | if(LEDR>0) 39 | { 40 | page +=""; 42 | } 43 | else 44 | { 45 | page +=""; 47 | } 48 | page +="
Green LED is ON now"; 31 | page +="Press to turn Green LED OFFGreen LED is OFF now"; 36 | page +="Press to turn Green LED ONRed LED is ON now"; 41 | page +="Press to turn Red LED OFFRed LED is OFF now"; 46 | page +="Press to turn Red LED ON
"; 49 | page +="

Counter is "+String(counter)+" now // include ESP8266 library 12 | ESP8266WebServer server; 13 | int LEDGpin = D7; // define LED pins 14 | int LEDRpin = D8; 15 | #elif ESP32 16 | #include // include ESP32 library 17 | WebServer server (80); 18 | int LEDGpin = 26; // define LED pins 19 | int LEDRpin = 25; 20 | #else // Arduino IDE error message 21 | #error "ESP8266 or ESP32 microcontroller only" 22 | #endif 23 | -------------------------------------------------------------------------------- /Chapter 7/Listing7-3/Listing7-3.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: HTML code for WLAN webpage 3 | * Description: Webpage code for Listing 7-1 4 | * Created on: October 2020 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 7 - Wireless local area network 8 | ******************************************************************************/ 9 | 10 | String webcode(int LEDG, int LEDR, int counter) 11 | { 12 | String page = ""; 13 | page +="Local network"; 14 | page +=""; 25 | page +=""; 26 | page +="

ESP8266 local area network

"; 27 | page +=""; 28 | if(LEDG>0) 29 | { 30 | page +=""; 32 | } 33 | else 34 | { 35 | page +=""; 37 | } 38 | if(LEDR>0) 39 | { 40 | page +=""; 42 | } 43 | else 44 | { 45 | page +=""; 47 | } 48 | page +="
Green LED is ON now"; 31 | page +="Press to turn Green LED OFFGreen LED is OFF now"; 36 | page +="Press to turn Green LED ONRed LED is ON now"; 41 | page +="Press to turn Red LED OFFRed LED is OFF now"; 46 | page +="Press to turn Red LED ON
"; 49 | page +="

Counter is "+String(counter)+" now // start of JavaScript 11 | var xhr = new XMLHttpRequest(); // XMLHttpRequest object 12 | xhr.onreadystatechange = function() 13 | { 14 | if(this.readyState == 4 && this.status == 200) // [1] if request successful 15 | // [2] update variable 16 | document.getElementById(variable).innerHTML = this.responseText; 17 | }; 18 | xhr.open('GET', URL, true); // [3] at URL 19 | xhr.send(); 20 | // end of JavaScript 21 | -------------------------------------------------------------------------------- /Chapter 7/Listing7-5/Listing7-5.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: AJAX code for updating a variable 3 | * Description: Example of an AJAX function (used in Listing 7-6) 4 | * Created on: October 2020 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 7 - Wireless local area network 8 | ******************************************************************************/ 9 | 10 | function sendData(butn) 11 | { 12 | if(butn == 'Red LED' || butn == 'Green LED') 13 | { 14 | var state = document.getElementById(butn).className; 15 | state = (state == 'btn on' ? 'btn off' : 'btn on'); 16 | text = (state == 'btn on' ? butn + ' OFF' : butn + ' ON'); 17 | document.getElementById(butn).className = state; 18 | document.getElementById(butn).innerHTML = 'Press to turn ' + text; 19 | } 20 | var URL, variab, text; 21 | 22 | else if(butn == 'Green LED') 23 | { 24 | URL = 'LEDGurl'; 25 | variab = 'LEDG'; 26 | } 27 | var xhr = new XMLHttpRequest(); 28 | xhr.onreadystatechange = function(butn) 29 | { 30 | if (this.readyState == 4 && this.status == 200) 31 | document.getElementById(variab).innerHTML = this.responseText; 32 | }; 33 | xhr.open('GET', URL, true); 34 | xhr.send(); 35 | } 36 | -------------------------------------------------------------------------------- /Chapter 7/Listing7-6/Listing7-6.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: AJAX code for WLAN webpage 3 | * Description: Webpage control two LEDs (after revising Listing 7-1) 4 | * Created on: October 2020 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 7 - Wireless local area network 8 | ******************************************************************************/ 9 | 10 | char page[] PROGMEM = R"( 11 | 12 | Local network 13 | 24 | 25 |

ESP8266 local area network

26 | 27 | 28 | 29 |
Green LED is OFF nowRed LED is OFF now
30 | 31 | 33 | 35 |
36 |

Counter is 0 now

37 | 39 | 40 | 77 | 78 | )"; 79 | -------------------------------------------------------------------------------- /Chapter 7/Listing7-7/Listing7-7.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: AJAX code to periodically update counter 3 | * Description: Automated updating of counter on webpage (inclusion in Listing 7-6) 4 | * Created on: October 2020 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 7 - Wireless local area network 8 | ******************************************************************************/ 9 | 10 | setInterval(reload, 1000); 11 | function reload() 12 | { 13 | var xhr = new XMLHttpRequest(); 14 | xhr.onreadystatechange = function() 15 | { 16 | if(this.readyState == 4 && this.status == 200) 17 | document.getElementById('counter').innerHTML = this.responseText; 18 | }; 19 | xhr.open('GET', 'countUrl', true); 20 | xhr.send(); 21 | } 22 | -------------------------------------------------------------------------------- /Chapter 8/Listing8-1/Listing8-1.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: HTTP request with BMP280 and LED 3 | * Description: Update webpage with sensor information 4 | * Created on: October 2020 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 8 - Updating a webpage 8 | ******************************************************************************/ 9 | 10 | #include // include ESP8266WebServer lib 11 | ESP8266WebServer server; // associate server with library 12 | char ssid[] = "xxxx"; // change xxxx to Wi-Fi SSID 13 | char password[] = "xxxx"; // change xxxx to Wi-Fi password 14 | #include // include Unified Sensor 15 | #include // and BMP280 libraries 16 | Adafruit_BMP280 bmp; // associate bmp with BMP280 17 | int BMPaddress = 0x76; // I2C address of BMP280 18 | #include // include Ticker library 19 | Ticker timer; // associate timer with Ticker lib 20 | int lag = 10; // set timer interval at 10s 21 | int LEDpin = D3; // LED pin on D3 22 | String LED = "off"; // initial LED state 23 | int count = 0; 24 | String temp, counter; 25 | 26 | void setup() 27 | { 28 | Serial.begin(115200); // define Serial Monitor baud rate 29 | WiFi.begin(ssid, password); // initialise Wi-Fi 30 | while (WiFi.status() != WL_CONNECTED) delay(500); // wait for Wi-Fi connect 31 | Serial.print("IP address: "); 32 | Serial.println(WiFi.localIP()); // display server IP address 33 | server.begin(); 34 | server.on("/", webcode); // map URL to function 35 | bmp.begin(BMPaddress); // initialise BMP280 36 | timer.attach(lag, BMP); // BMP called every lag seconds 37 | pinMode(LEDpin, OUTPUT); 38 | digitalWrite(LEDpin, LOW); // turn off LED 39 | } 40 | 41 | void BMP() // function to get readings 42 | { 43 | temp = String(bmp.readTemperature()); // update BMP280 reading 44 | counter = String(count++); // increment counter 45 | digitalWrite(LEDpin, !digitalRead(LEDpin)); // turn on or off the LED 46 | if(LED == "on") LED = "off"; // update LED state 47 | else LED = "on"; 48 | server.send (200, "text/html", webcode()); // send response to client 49 | } 50 | 51 | String webcode() // return HTML code 52 | { 53 | String page; 54 | page = ""; 55 | page += ""; // refresh every 9s 56 | page += "ESP8266"; 57 | page += ""; 58 | page += "

BMP280

"; 59 | page += "

Temperature: " + temp + " " + "°C

"; // display temp 60 | page += "

Counter: " + counter + "

"; // counter 61 | page += "

LED is " + LED + "

"; // LED state 62 | page += ""; 63 | return page; 64 | } 65 | 66 | void loop() 67 | { 68 | server.handleClient(); 69 | } 70 | -------------------------------------------------------------------------------- /Chapter 8/Listing8-10/Listing8-10.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: Access information 3 | * Description: Example of storing access codes in library file 4 | * Created on: October 2020 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 8 - Updating a webpage 8 | ******************************************************************************/ 9 | 10 | char ssid[] = "PhoneNetwork12"; // Wi-Fi access 11 | char password[] = "difficu1t"; 12 | char APItime[] = "efth1234"; 13 | char APIdate[] = "mhtd5678"; // ThingSpeak API keys 14 | char APItemp[] = "plmf4567"; 15 | char APIhumid[] = "thkl6789"; 16 | char username[] = "ABC-234"; // Cayenne access 17 | char mqttpass[] = "XYZ-567"; 18 | char clientID[] = "GHJ-876"; 19 | -------------------------------------------------------------------------------- /Chapter 8/Listing8-2/Listing8-2.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: Pin definitions for ESP8266 and ESP32 development boards 3 | * Description: Code included at start of sketch for ESP8266 and ESP32 4 | * Created on: October 2020 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 8 - Updating a webpage 8 | ******************************************************************************/ 9 | 10 | #ifdef ESP32 11 | #include // include ESP32 library 12 | WebServer server (80); // and define LED pin 13 | int LEDpin = 23; 14 | #elif ESP8266 15 | #include // include ESP8266 library 16 | ESP8266WebServer server; // and define LED pin 17 | int LEDpin = D3; 18 | #else // Arduino IDE error message 19 | #error "ESP8266 or ESP32 microcontroller only" 20 | #endif 21 | -------------------------------------------------------------------------------- /Chapter 8/Listing8-3/Listing8-3.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: XML HTTP requests for BMP280 temperature, counter and LED state 3 | * Description: Revised functions for Listing 8-1 4 | * Created on: October 2020 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 8 - Updating a webpage 8 | ******************************************************************************/ 9 | 10 | void base() // function to load default webpage 11 | { // and send HTML code to client 12 | server.send (200, "text/html", page); 13 | } 14 | 15 | void tempFunct() // function to get temperature reading 16 | { // and send value to client 17 | temp = String(bmp.readTemperature()); 18 | server.send (200, "text/plain", temp); // send plain text not HTML code 19 | } 20 | 21 | void countFunct() // function to increment counter 22 | { // and send value to client 23 | counter = String(count++); 24 | server.send (200, "text/plain", counter); 25 | } 26 | 27 | void LEDfunct() // function to update LED 28 | { // and send LED state to client 29 | digitalWrite(LEDpin, !digitalRead(LEDpin)); 30 | if(LED == "on") LED = "off"; 31 | else LED = "on"; 32 | server.send (200, "text/plain", LED); 33 | } 34 | -------------------------------------------------------------------------------- /Chapter 8/Listing8-4/Listing8-4.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: AJAX request with BMP280 and LED 3 | * Description: Webpage code for revised Listing 8-1 4 | * Created on: October 2020 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 8 - Updating a webpage 8 | ******************************************************************************/ 9 | 10 | char page[] PROGMEM = R"( 11 | 12 | ESP8266 13 | 14 |

BMP280

15 |

Temperature: 0°C

16 |

Counter: 0

17 |

LED is

18 | 19 | 55 | 56 | )"; 57 | -------------------------------------------------------------------------------- /Chapter 8/Listing8-5/Listing8-5.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: AJAX code with JSON parsing 3 | * Description: Webpage code with JSON for revised Listing 8-1 4 | * Created on: October 2020 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 8 - Updating a webpage 8 | ******************************************************************************/ 9 | 10 | char page[] PROGMEM = R"( 11 | 12 | ESP8266 13 | 14 |

BMP280

15 |

Temperature: 0°C

16 |

Counter: 0

17 |

LED is

18 | 19 | 50 | 51 | )"; 52 | -------------------------------------------------------------------------------- /Chapter 8/Listing8-7/Listing8-7.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: AJAX code with JSON parsing 3 | * Description: Webpage code to display ThingSpeak data - combine with Listing 8-6 4 | * Created on: October 2020 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 8 - Updating a webpage 8 | ******************************************************************************/ 9 | 10 | char page[] PROGMEM = R"( 11 | 12 | ESP8266 13 | 14 |

BMP280

15 |

Date: 00 000 0000

16 |

Time: 00:00:00

17 |

Temp is 0°C

18 |

Humidity is 0%

19 | 20 | 40 | 41 | )"; 42 | -------------------------------------------------------------------------------- /Chapter 8/Listing8-9/Listing8-9.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: Alarm, LED and light intensity 3 | * Description: email notification of triggered alarm with Cayenne MQTT broker 4 | * Created on: October 2020 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 8 - Updating a webpage 8 | ******************************************************************************/ 9 | 10 | #include // Cayenne MQTT library 11 | char ssid[] = "xxxx"; // change xxxx to your Wi-Fi ssid 12 | char password[] = "xxxx"; // change xxxx to your Wi-Fi password 13 | char username[] = "xxxx"; // change xxxx to Cayenne username 14 | char mqttpass[] = "xxxx"; // change xxxx to Cayenne password 15 | char clientID[] = "xxxx"; // change xxxx to Cayenne client identity 16 | int LEDpin = D3; 17 | int alarmPin = D5; // define LED, alarm and LDR pins 18 | int LDRpin = A0; 19 | int flashPin = D4; // flashing LED 20 | int reading, alarm, alert; 21 | int interval = 2000; // 2s interval between LDR readings 22 | unsigned long LDRtime = 0; 23 | 24 | void setup() 25 | { 26 | Cayenne.begin(username, mqttpass, clientID, ssid, password); 27 | pinMode(LEDpin, OUTPUT); // define LED and alarm pins as output 28 | pinMode(alarmPin, OUTPUT); 29 | pinMode(flashPin, OUTPUT); 30 | alarm = 0; // set alarm to OFF 31 | } 32 | 33 | void loop() 34 | { 35 | Cayenne.loop(); // Cayenne loop function 36 | if(millis() - LDRtime > interval) 37 | { 38 | LDRtime = millis(); 39 | reading = analogRead(LDRpin); 40 | if (alarm == 1) Cayenne.virtualWrite(V1, reading, "lum", "lux"); 41 | else Cayenne.virtualWrite(V1, 0, "lum", "lux"); 42 | digitalWrite(flashPin, LOW); 43 | delay(10); // flash LED to indicate power on 44 | digitalWrite(flashPin, HIGH); 45 | } 46 | } 47 | 48 | CAYENNE_IN(0) // Cayenne virtual channel 0 49 | { 50 | alert = getValue.asInt(); // get alarm triggered status 51 | digitalWrite(LEDpin, alert); // update alarm triggered LED 52 | } 53 | CAYENNE_IN(3) // Cayenne virtual channel 3 54 | { 55 | alarm = getValue.asInt(); // get alarm set state 56 | digitalWrite(alarmPin, alarm); // update alarm set indicator LED 57 | } 58 | -------------------------------------------------------------------------------- /Chapter 8_NEW/Listing8-8_NEW/Listing8-8_NEW.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: Blynk, ESP8266 with LED, LDR and BMP820 sensor 3 | * Description: Display sensor data and control LED on Blynk dashboard 4 | * Created on: October 2023 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 8 - Updating a webpage 8 | ******************************************************************************/ 9 | 10 | #define BLYNK_TEMPLATE_ID "xxxx" // change xxxx to Template details 11 | #define BLYNK_TEMPLATE_NAME "Listing88" 12 | #define BLYNK_AUTH_TOKEN "xxxx" // change xxxx to Authentication token 13 | #define BLYNK_PRINT Serial 14 | //#include // called by BlynkSimpleEsp8266 15 | #include 16 | #include 17 | #include // include Adafruit_Sensor library 18 | #include // include Adafruit_BMP280 library 19 | Adafruit_BMP280 bmp; // associate bmp with BMP280 library 20 | int LEDpin = D3; // LED pin 21 | int LDRpin = A0; // light dependent resistor pin 22 | int flashPin = D4; // flashing LED pin 23 | int count = 0; 24 | int interval = 10000; // 10s interval between MQTT messages 25 | float temp, pressure; 26 | int light; 27 | 28 | BlynkTimer timer; 29 | void timerEvent() 30 | { 31 | temp = bmp.readTemperature(); // BMP280 temperature 32 | pressure = bmp.readPressure()/100.0; // and pressure 33 | light = analogRead(LDRpin); // ambient light intensity 34 | light = constrain(light, 0, 1023); // constrain light reading 35 | count++; // increment counter 36 | if(count>99) count = 0; 37 | digitalWrite(flashPin, LOW); // turn on then off flashing LED 38 | delay(10); 39 | digitalWrite(flashPin, HIGH); // send readings to Blynk on virtual pins 40 | Blynk.virtualWrite(V1, temp); // temperature 41 | Blynk.virtualWrite(V3, pressure); // pressure 42 | Blynk.virtualWrite(V5, light); // luminosity 43 | Blynk.virtualWrite(V6, count); // counter 44 | } 45 | 46 | BLYNK_WRITE(V0) // Blynk virtual pin 0 47 | { 48 | digitalWrite(LEDpin, param.asInt()); // turn on or off LED 49 | } 50 | 51 | BLYNK_CONNECTED() 52 | { 53 | Serial.println("ESP8266 connected to Blynk"); 54 | } 55 | 56 | void setup() 57 | { 58 | Serial.begin(115200); 59 | Serial.println();Serial.println(); 60 | Blynk.begin(BLYNK_AUTH_TOKEN, ssidEXT, password, "blynk.cloud", 80); 61 | timer.setInterval(interval, timerEvent); 62 | bmp.begin(0x76); // initiate bmp with I2C address 63 | pinMode(LEDpin, OUTPUT); // define LED pins as output 64 | digitalWrite(LEDpin, LOW); 65 | pinMode(flashPin, OUTPUT); 66 | } 67 | 68 | void loop() 69 | { 70 | Blynk.run(); // 71 | timer.run(); 72 | } 73 | -------------------------------------------------------------------------------- /Chapter 8_NEW/Listing8-9_NEW/Listing8-9_NEW.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: Alarm, LED and light intensity 3 | * Description: email notification of triggered alarm with Blynk MQTT broker 4 | * Created on: October 2023 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 8 - Updating a webpage 8 | ******************************************************************************/ 9 | 10 | #define BLYNK_TEMPLATE_ID "xxxx" // change xxxx to Template details 11 | #define BLYNK_TEMPLATE_NAME "Listing89" 12 | #define BLYNK_AUTH_TOKEN "xxxx" // change xxxx to Authentication token 13 | #define BLYNK_PRINT Serial 14 | //#include // called by BlynkSimpleEsp8266 15 | #include 16 | #include 17 | int LEDpin = D3; 18 | int alarmPin = D5; // define LED, alarm and LDR pins 19 | int LDRpin = A0; 20 | int flashPin = D4; // flashing LED 21 | int reading, alarm, alert; 22 | unsigned long lag = 0; 23 | int flag; 24 | 25 | BlynkTimer timer; 26 | void timerEvent() 27 | { 28 | reading = analogRead(LDRpin); 29 | if (alarm == 1) Blynk.virtualWrite(V1, reading); 30 | else Blynk.virtualWrite(V1, 0); 31 | digitalWrite(flashPin, LOW); 32 | delay(10); // flash LED to indicate power on 33 | digitalWrite(flashPin, HIGH); 34 | 35 | if(alarm == 1 && reading > 400 && flag == 0) 36 | { 37 | Blynk.virtualWrite(V0, 1); 38 | Blynk.logEvent("alert", "light value above 400: " + String(reading)); 39 | digitalWrite(LEDpin, alarm); 40 | flag = 1; 41 | } 42 | else if (reading < 400 && flag == 1) flag = 0; 43 | } 44 | 45 | BLYNK_WRITE(0) // Blynk virtual pin 0 46 | { 47 | alert = param.asInt(); // get alarm triggered status 48 | digitalWrite(LEDpin, alert); // update alarm triggered LED 49 | } 50 | BLYNK_WRITE(3) // Blynk virtual pin 3 51 | { 52 | alarm = param.asInt(); // get alarm set state 53 | digitalWrite(alarmPin, alarm); // update alarm set indicator LED 54 | } 55 | 56 | BLYNK_CONNECTED() 57 | { 58 | Serial.println("ESP8266 connected to Blynk"); 59 | } 60 | 61 | void setup() 62 | { 63 | Serial.begin(115200); 64 | Serial.println();Serial.println(); 65 | Blynk.begin(BLYNK_AUTH_TOKEN, ssidEXT, password, "blynk.cloud", 80); 66 | timer.setInterval(2000, timerEvent); 67 | pinMode(LEDpin, OUTPUT); // define LED and alarm pins as output 68 | pinMode(alarmPin, OUTPUT); 69 | pinMode(flashPin, OUTPUT); 70 | alarm = 0; // set alarm to OFF 71 | } 72 | 73 | void loop() 74 | { 75 | Blynk.run(); // 76 | timer.run(); 77 | } 78 | -------------------------------------------------------------------------------- /Chapter 8_NEW/NEW Chapter 8 Updating a webpage.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/ESP8266-and-ESP32/3f223c897ff3952af75b4a12e4430d87d1927590/Chapter 8_NEW/NEW Chapter 8 Updating a webpage.pdf -------------------------------------------------------------------------------- /Chapter 9/Listing9-1/Listing9-1.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: WebSocket main sketch 3 | * Description: two-way coversation between server and client displayed on webpage 4 | * Created on: October 2020 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 9 - WebSocket 8 | ******************************************************************************/ 9 | 10 | #include // include Webserver library 11 | ESP8266WebServer server; // associate server with library 12 | #include // include WebSocket library 13 | WebSocketsServer websocket = WebSocketsServer(81); // set WebSocket port 81 14 | #include "buildpage.h" // webpage AJAX code 15 | char ssid[] = "xxxx"; // change xxxx to Wi-Fi SSID 16 | char password[] = "xxxx"; // change xxxx to Wi-Fi password 17 | String str; 18 | 19 | void setup() 20 | { 21 | Serial.begin(115200); // define Serial Monitor baud rate 22 | WiFi.begin(ssid, password); // connect and initialise Wi-Fi 23 | while (WiFi.status() != WL_CONNECTED) delay(500); 24 | Serial.print("IP address: "); 25 | Serial.println(WiFi.localIP()); // display web server IP address 26 | server.begin(); 27 | server.on("/", base); // load default webpage 28 | websocket.begin(); // initialise WebSocket 29 | websocket.onEvent(wsEvent); // call wsEvent function 30 | } // on WebSocket event 31 | 32 | void wsEvent(uint8_t num, WStype_t type, uint8_t * message, size_t length) 33 | { 34 | if(type == WStype_TEXT) // when text received from client 35 | { // display text on Serial Monitor 36 | for(int i=0; i 0) 46 | { // read text in Serial buffer 47 | str = Serial.readString(); // and send to client 48 | websocket.broadcastTXT(str.c_str(), str.length()); 49 | } 50 | } 51 | 52 | void base() // function for default webpage 53 | { 54 | server.send (200, "text/html", page); 55 | } 56 | -------------------------------------------------------------------------------- /Chapter 9/Listing9-2/Listing9-2.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: WebSocket webpage AJAX code 3 | * Description: webpage code to display server-client conversation for Listing 9-1 4 | * Created on: October 2020 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 9 - WebSocket 8 | ******************************************************************************/ 9 | 10 | char page[] PROGMEM = R"( 11 | 12 | ESP8266 13 | 19 | 20 |

WebSocket

21 | 22 | 23 | 24 | 25 | 29 | 30 |
transmit textreceive text (click to clear)
26 |
27 | 28 |

31 | 32 | 51 | 52 | )"; 53 | -------------------------------------------------------------------------------- /Chapter 9/Listing9-5/Listing9-5.ino: -------------------------------------------------------------------------------- 1 | /******************************************************************************* 2 | * Sketch name: Servo motor calibration 3 | * Description: determine square wave pulse length to move servo motor 4 | * Created on: October 2020 5 | * Author: Neil Cameron 6 | * Book: Electronics Projects with the ESP8266 and ESP32 7 | * Chapter : 9 - WebSocket 8 | ******************************************************************************/ 9 | 10 | #include // include Servo library 11 | Servo servoFB; // associate servoFB with servo library 12 | int FBpin = D7; // servo pin 13 | int microsec; 14 | 15 | void setup() 16 | { 17 | Serial.begin(115200); // define Serial Monitor baud rate 18 | servoFB.attach(FBpin); // initialise servo motor 19 | } 20 | 21 | void loop() 22 | { 23 | if(Serial.available() > 0) // text entered in Serial Monitor 24 | { 25 | microsec = Serial.parseInt(); // parse text to integer 26 | servoFB.writeMicroseconds(microsec); // move servo motor 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Contributing.md: -------------------------------------------------------------------------------- 1 | # Contributing to Apress Source Code 2 | 3 | Copyright for Apress source code belongs to the author(s). However, under fair use you are encouraged to fork and contribute minor corrections and updates for the benefit of the author(s) and other readers. 4 | 5 | ## How to Contribute 6 | 7 | 1. Make sure you have a GitHub account. 8 | 2. Fork the repository for the relevant book. 9 | 3. Create a new branch on which to make your change, e.g. 10 | `git checkout -b my_code_contribution` 11 | 4. Commit your change. Include a commit message describing the correction. Please note that if your commit message is not clear, the correction will not be accepted. 12 | 5. Submit a pull request. 13 | 14 | Thank you for your contribution! -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Freeware License, some rights reserved 2 | 3 | Copyright (c) 2020 Neil Cameron 4 | 5 | Permission is hereby granted, free of charge, to anyone obtaining a copy 6 | of this software and associated documentation files (the "Software"), 7 | to work with the Software within the limits of freeware distribution and fair use. 8 | This includes the rights to use, copy, and modify the Software for personal use. 9 | Users are also allowed and encouraged to submit corrections and modifications 10 | to the Software for the benefit of other users. 11 | 12 | It is not allowed to reuse, modify, or redistribute the Software for 13 | commercial use in any way, or for a user’s educational materials such as books 14 | or blog articles without prior permission from the copyright holder. 15 | 16 | The above copyright notice and this permission notice need to be included 17 | in all copies or substantial portions of the software. 18 | 19 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | AUTHORS OR COPYRIGHT HOLDERS OR APRESS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 25 | SOFTWARE. 26 | 27 | 28 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Apress Source Code 2 | 3 | This repository accompanies [*Electronics Projects with the ESP8266 and ESP32: Building Web Pages, Applications, and WiFi Enabled Devices*](https://www.apress.com/9781484263358) by Neil Cameron (Apress, 2020). 4 | 5 | [comment]: #cover 6 | ![Cover image](9781484263358.jpg) 7 | 8 | Download the files as a zip using the green button, or clone the repository to your machine using Git. 9 | 10 | ## Releases 11 | 12 | Release v1.0 corresponds to the code in the published book, without corrections or updates. 13 | 14 | ## Contributions 15 | 16 | See the file Contributing.md for more information on how you can contribute to this repository. -------------------------------------------------------------------------------- /Updates and corrections Oct 2023/Updates and corrections Oct 2023.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Apress/ESP8266-and-ESP32/3f223c897ff3952af75b4a12e4430d87d1927590/Updates and corrections Oct 2023/Updates and corrections Oct 2023.pdf --------------------------------------------------------------------------------