Skip to content

Instantly share code, notes, and snippets.

@IdrisCytron
Last active March 24, 2020 04:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save IdrisCytron/38b32673a5baccefc3951b8a972df691 to your computer and use it in GitHub Desktop.
Save IdrisCytron/38b32673a5baccefc3951b8a972df691 to your computer and use it in GitHub Desktop.
Send Data Wirelessly Between ESP32 Using ESPNow.
/*
Tutorial: Build Your Own Portable Contactless Temperature Reader
Hardware:
- TTGO T-Display ESP32
https://my.cytron.io/p-ttgo-t-display-esp32-1.14-display-module-presolder-header?tracking=idris
- MLX90614 Non-Contact Infrared Temperature Sensor
https://my.cytron.io/p-mlx90614-non-contact-infrared-temperature-sensor?tracking=idris
External libraries:
- TFT_eSPI by Bodmer Version 1.4.20
- Adafruit MLX90614 Library by Adafruit Version 1.0.1
Created by:
24 Mar 2020 Idris Zainal Abidin, Cytron Technologies
*/
#include <esp_now.h>
#include <WiFi.h>
#include <TFT_eSPI.h>
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_MLX90614.h>
const byte broadcastAddress[] = {0x30, 0xAE, 0xA4, 0xF6, 0xCD, 0xB8}; // Replace with your ESP board MAC Address
#define ADC_PIN 34
#define VREF 1100
#define BUTTON1 35
#define BUTTON2 0
#define FF17 &FreeSans9pt7b
#define FF21 &FreeSansBold9pt7b
#define ROW1 0,16
#define ROW2 0,38
#define ROW3 0,60
#define ROW4 0,82
#define ROW5 0,104
#define ROW6 0,126
TFT_eSPI tft = TFT_eSPI();
Adafruit_MLX90614 mlx = Adafruit_MLX90614();
float ambientCelsius = 0.0;
float objectCelsius = 0.0;
float objectCelsiusTotal = 0.0;
long prevMillis = 0;
int interval = 1000;
// callback when data is sent
void OnDataSent(const byte *mac_addr, esp_now_send_status_t status)
{
Serial.print("\r\nLast Packet Send Status:\t");
Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Delivery Success" : "Delivery Fail");
}
void setup()
{
pinMode(BUTTON1, INPUT_PULLUP);
pinMode(BUTTON2, INPUT_PULLUP);
Serial.begin(115200);
Serial.println();
Serial.println("Build your own Portable Contactless Temperature Reader for Covid-19");
Serial.println();
WiFi.mode(WIFI_STA);
// Init ESP-NOW
if (esp_now_init() != ESP_OK) {
Serial.println("Error initializing ESP-NOW");
return;
}
// Once ESPNow is successfully Init, we will register for Send CB to
// get the status of Trasnmitted packet
esp_now_register_send_cb(OnDataSent);
// Register peer
esp_now_peer_info_t peerInfo;
memcpy(peerInfo.peer_addr, broadcastAddress, 6);
peerInfo.channel = 0;
peerInfo.encrypt = false;
// Add peer
if (esp_now_add_peer(&peerInfo) != ESP_OK){
Serial.println("Failed to add peer");
return;
}
tft.init();
tft.setRotation(1);
tft.fillScreen(TFT_BLACK);
tft.fillRect(0, 0, 240, 43, TFT_DARKGREY);
tft.setFreeFont(FF21);
tft.setTextColor(TFT_BLACK);
tft.setCursor(ROW1);
tft.print(" Portable Contactless");
tft.setCursor(0, 35); // Row 2
tft.print(" Temperature Reader");
tft.setTextColor(TFT_WHITE);
tft.setCursor(ROW3);
tft.print(" Battery:");
tft.setTextColor(TFT_CYAN);
tft.setCursor(ROW4);
tft.print(" < Press button to read >");
tft.setTextColor(TFT_WHITE);
tft.setCursor(ROW5);
tft.print(" Celsius:");
tft.fillRect(0, 112, 240, 23, TFT_MAROON);
tft.setTextColor(TFT_BLACK);
tft.setCursor(0, 128); // Row 6
tft.print(" #Covid19 by Idris");
mlx.begin();
}
void loop()
{
if (millis() - prevMillis > interval) {
int adc = analogRead(ADC_PIN);
float batteryVoltage = ((float)adc/4095.0)*2.0*3.3*(VREF/1000.0);
tft.fillRect(140, 48, 100, 20, TFT_BLACK);
if (batteryVoltage > 4.2) {
tft.setTextColor(TFT_BLUE);
tft.setCursor(140, 60);
tft.print("Charge");
}
else {
batteryVoltage = constrain(batteryVoltage, 3, 4);
float batteryPercent = ((batteryVoltage - 3) / 1) * 100;
if (batteryPercent < 50) {
tft.setTextColor(TFT_RED);
}
else if (batteryPercent < 80) {
tft.setTextColor(TFT_YELLOW);
}
else {
tft.setTextColor(TFT_GREEN);
}
tft.setCursor(150, 60);
tft.print((int)batteryPercent);
tft.print(" %");
}
prevMillis = millis();
}
if (digitalRead(BUTTON2) == LOW) {
objectCelsiusTotal = 0.0;
for (int i = 0; i < 20; i++) {
// ambientCelsius = mlx.readAmbientTempC();
objectCelsius = mlx.readObjectTempC();
objectCelsiusTotal += objectCelsius;
delay(50);
}
objectCelsius = objectCelsiusTotal / 20;
int celsius = objectCelsius;
tft.fillRect(140, 92, 100, 14, TFT_BLACK);
tft.setTextColor(TFT_GREEN);
tft.setCursor(150, 104);
tft.print(objectCelsius);
esp_err_t result = esp_now_send(broadcastAddress, (uint8_t *) &celsius, sizeof(celsius));
if (result == ESP_OK) {
Serial.println("Sent with success");
}
else {
Serial.println("Error sending the data");
}
}
}
/*
Project: Wireless Display with ESPNow
Board: ESP32 Dev Module
Mac Address: 30:AE:A4:F6:CD:B8
Hardware:
- Node32 Lite
https://my.cytron.io/p-node32-lite-wifi-and-bluetooth-development-kit?tracking=idris
- 4 In 1 MAX7219 Dot Matrix Display Module
https://my.cytron.io/p-4-in-1-max7219-dot-matrix-display-module?tracking=idris
Connections:
ESP32 | Dot Matrix
RAW - VCC
GND - GND
27 - DIN
26 - CS
25 - CLK
External libraries:
- MD_MAX72XX by majicDesigns Version 3.2.1 (Manager)
- MD_Parola by majicDesigns Version 3.3.0 (Manager)
Created by:
24 Mar 2020 Idris Zainal Abidin, Cytron Technologies
*/
#include <esp_now.h>
#include <WiFi.h>
#include <MD_Parola.h>
#include <MD_MAX72xx.h>
#include <SPI.h>
#define HARDWARE_TYPE MD_MAX72XX::FC16_HW
//#define HARDWARE_TYPE MD_MAX72XX::ICSTATION_HW
#define MAX_DEVICES 4
#define CLK_PIN 25 // 18 or 25
#define DATA_PIN 27 // 16 or 27
#define CS_PIN 26 // 17 or 26
MD_Parola DotMatrix = MD_Parola(HARDWARE_TYPE, DATA_PIN, CLK_PIN, CS_PIN, MAX_DEVICES);
#define BUZZER 23
#define NOTE_C4 262
#define NOTE_D4 294
#define NOTE_G4 392
#define NOTE_A4 440
#define playReadyMelody() playTone(melody1, melody1Dur, 2)
#define playNote1() playTone(melody2, melody2Dur, 1)
#define playNote2() playTone(melody3, melody3Dur, 1)
#define playBatteryWeak() playTone(melody4, melody1Dur, 2)
int melody1[] = {NOTE_C4, NOTE_G4};
int melody1Dur[] = {12, 8};
int melody2[] = {NOTE_A4};
int melody2Dur[] = {8};
int melody3[] = {NOTE_D4};
int melody3Dur[] = {8};
int melody4[] = {NOTE_G4, NOTE_C4};
int melody4Dur[] = {12, 8};
int celsius;
char textDotMatrix[6];
// callback when data is recv from Master
void OnDataRecv(const uint8_t *mac_addr, const uint8_t *incomingData, int data_len) {
char macStr[18];
snprintf(macStr, sizeof(macStr), "%02x:%02x:%02x:%02x:%02x:%02x",
mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);
memcpy(&celsius, incomingData, sizeof(celsius));
String text = String(celsius) + " °C";
Serial.print("Last Packet Recv from: "); Serial.println(macStr);
Serial.print("Last Packet Recv Data: "); Serial.println(text);
Serial.println(" °C");
sprintf(textDotMatrix, "%d\x90""C", (int)celsius);
DotMatrix.write(textDotMatrix);
playNote1();
}
void setup()
{
Serial.begin(115200);
DotMatrix.begin();
DotMatrix.setIntensity(1);
DotMatrix.setTextAlignment(PA_CENTER);
DotMatrix.print("...");
WiFi.mode(WIFI_STA);
// Init ESP-NOW
if (esp_now_init() != ESP_OK) {
Serial.println("Error initializing ESP-NOW");
return;
}
DotMatrix.setTextAlignment(PA_CENTER);
DotMatrix.print("Ready");
// Once ESPNow is successfully Init, we will register for recv CB to
// get recv packer info
esp_now_register_recv_cb(OnDataRecv);
playReadyMelody();
}
void loop()
{
}
const int FREQUENCY = 2000;
const int CHANNEL = 0;
const int RESOLUTION = 8;
void playTone(int *melody, int *melodyDur, int notesLength)
{
for (int i = 0; i < notesLength; i++) {
ledcAttachPin(BUZZER, CHANNEL);
int noteDuration = 1000 / melodyDur[i];
ledcWriteTone(CHANNEL, melody[i]);
int pauseBetweenNotes = noteDuration * 1.30;
delay(pauseBetweenNotes);
ledcDetachPin(BUZZER);
ledcWrite(CHANNEL, 0);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment