Hi guys, hoping to narrow down why my project is performing a bit unpredictably. Any suggestions and help is greatly appreciated.
I have two NodeMCU ESP8266s. One is a transmitter/client ESP with an array of hall effect sensors, which transmits their state over wifi (UDP) to a receiver/server ESP, that displays a number (that represents the magnet state) on a MAX7219 8x8 LED matrix. This was working very well when the receiver/server had a TM1637 7-segment LED display (I2C), but upon changing to the MAX7219 (SPI), the display does not always update/receive the transmitted packet. When moving a magnet near or away from a sensor, sometimes (probably 50% of the time) the display does not update, and stays on the current number.
I've tried troubleshooting, but am a bit confused as to why the display has made such a difference (I assume it's the change to SPI). Any help is greatly appreciated, as always. Below code is transmitter/client, followed by the receiver/server.
(the receiver/server code has a lot of TM1637 code commented out, as it's a work in progress)
Transmitter/Client Side
// NodeMCU ESP8266-based manual gear shifter detector & display using the MAX7219 8x8 LED Matrix
// module. 3x A3144 Hall Effect Sensors are connected via pins 2, 3 & 12, and when a magnet/s is
// present, will display gear One (pin 2), Gear Two (pin 3), Gear Three (pin 12), Gear Four (Pins
// 2 & 12), Gear Five (Pins 3 & 12), and Reverse (pins 2 & 3) - otherwise Neutral is displayed.
//Hall effect sensor coding is a modified example as provided by Arduino Forum member johnwasser.
//https://forum.arduino.cc/t/my-codes-inefficiency/851135/9
//UDP server/client scripts heavily modified based upon Siytek.com example.
//https://siytek.com/communication-between-two-esp8266/
// ***********Sensor/Transmitter/Client Side************
#include "TM1637Display.h"
#include "ESP8266WiFi.h"
#include "WiFiUdp.h"
#define WIFI_SSID "E36GearShifter" // Set WiFi credentials
#define WIFI_PASS "owwmyfrickenexpansiontank"
WiFiUDP UDP; // UDP
IPAddress remote_IP(192,168,4,1);
#define UDP_PORT 4210
const int CLK = D1; // Set the CLK pin connection to the display
const int DIO = D2; // Set the DIO pin connection to the display
const uint8_t blank[] = {0x00, 0x00, 0x00, 0x00}; // Declares the value of "blank"
const uint8_t data[] = {0xff, 0xff, 0xff, 0xff}; // Declares "data" as all segments on
const uint8_t n[] = // Required segments to display the character "n"
{
SEG_C | SEG_E | SEG_G
};
const uint8_t r[] =
{
SEG_E | SEG_G
}; // Required segments to display the character "r"
TM1637Display display(CLK, DIO); //set up the 4-Digit Display.
// int TM1637Display(CLK, DIO);
const int FirstGearPin = D0;
const int SecondGearPin = D3;
const int UpperGearsPin = D4;
const int ledPinD5 = D5;
const int ledPinD6 = D6;
const int ledPinD7 = D7;
const char * GearNames[8] =
{
"Neutral", // 0
"First Gear", // 1 (FirstGearPin)
"Second Gear", // 2 (SecondGearPin)
"Reverse", // 3 (FirstGearPin + SecondGearPin)
"Third Gear", // 4 (UpperGearsPin alone)
"Fourth Gear", // 5 (FirstGearPin + UpperGearsPin)
"Fifth Gear", // 6 (SecondGearPin + UpperGearsPin)
"INVALID" // 7 (FirstGearPin + SecondGearPin + UpperGearsPin)
};
enum Gears {Neutral, First, Second, Reverse, Third, Fourth, Fifth};
int counter = 0;
void setup()
{
Serial.begin(115200); // Setup serial monitor
pinMode(FirstGearPin, INPUT);
pinMode(SecondGearPin, INPUT);
pinMode(UpperGearsPin, INPUT);
pinMode(ledPinD5, OUTPUT);
pinMode(ledPinD6, OUTPUT);
pinMode(ledPinD7, OUTPUT);
WiFi.begin(WIFI_SSID, WIFI_PASS); // Begin WiFi
WiFi.mode(WIFI_STA);
//Serial.print("Connecting to "); // Connecting to WiFi...
//Serial.print(WIFI_SSID);
//while (WiFi.status() != WL_CONNECTED) // Loop continuously while WiFi is not connected
//{
// delay(100);
//Serial.print(".");
//}
//Serial.println(); // Connected to WiFi
//Serial.print("Connected! IP address: ");
//Serial.println(WiFi.localIP());
UDP.begin(UDP_PORT); // Begin UDP port
Serial.print("Opening UDP port ");
Serial.println(UDP_PORT);
display.clear(); // Clear display
display.setBrightness(7); // Set the diplay to maximum brightness
display.setSegments(blank); // Clear display
}
void DisplayGear(enum Gears gear)
{
// Set the LEDs to match the sensor inputs.
digitalWrite(ledPinD5, gear & 1);
digitalWrite(ledPinD6, gear & 2);
digitalWrite(ledPinD7, gear & 4);
printMessage(GearNames[gear]);
display.clear();
switch (gear)
{
case Neutral:
display.setSegments(n, 1, 3);
break;
case First:
case Second:
display.showNumberDec(gear, false, 4);
break;
case Reverse:
display.setSegments(r, 1, 3);
break;
case Third:
case Fourth:
case Fifth:
display.showNumberDec(gear - 1, false, 4);
break;
default:
break;
}
}
void loop()
{
static byte previousGear = 7;
byte currentGear = (digitalRead(FirstGearPin) == LOW)
+ ((digitalRead(SecondGearPin) == LOW) << 1)
+ ((digitalRead(UpperGearsPin) == LOW) << 2);
if (currentGear == previousGear)
return; // Nothing to do if the gear has not changed
previousGear = currentGear;
DisplayGear((enum Gears)currentGear);
UDP.beginPacket(remote_IP, UDP_PORT); // Send packet
UDP.write(currentGear);
UDP.endPacket();
delay(100);
}
void printMessage(String message)
{
counter++;
Serial.print(counter);
Serial.print(" ");
Serial.println(message);
//delay(200);
}
Receiver/Server Side
// NodeMCU ESP8266-based manual gear shifter detector & display using the MAX7219 8x8 LED Matrix
// module. 3x A3144 Hall Effect Sensors are connected via pins 2, 3 & 12, and when a magnet/s is
// present, will display gear One (pin 2), Gear Two (pin 3), Gear Three (pin 12), Gear Four (Pins
// 2 & 12), Gear Five (Pins 3 & 12), and Reverse (pins 2 & 3) - otherwise Neutral is displayed.
//Hall effect sensor coding is a modified example as provided by Arduino Forum member johnwasser.
//https://forum.arduino.cc/t/my-codes-inefficiency/851135/9
//UDP server/client scripts heavily modified based upon Siytek.com example.
//https://siytek.com/communication-between-two-esp8266/
// ***********Receiver/Display/Server Side***********
#include "ESP8266WiFi.h"
#include "WiFiUdp.h"
#include "LedControl.h"
//#include "TM1637Display.h"
int DIN = D0; //Set the DIN/?Didigtal IN pin
int CS = D1; //Set the CS/?Chip Select pin
int CLK = D2; //Set the CLK/Clock pin
LedControl lc=LedControl(DIN, CLK, CS, 0);
//Set gear numbers as bytes for the display
int One[8] ={B00000000,B00011000,B00111000,B00011000,B00011000,B00011000,B00111100,B00000000};
byte Two [8]={B00000000,B00011000,B00100100,B00000100,B00001000,B00010000,B00111100,B00000000};
byte Three [8]={B00000000,B00111000,B00000100,B00011000,B00001100,B00000100,B00111000,B00000000};
byte Four [8]={B00000000,B00000100,B00001100,B00010100,B00100100,B01111110,B00000100,B00000000};
byte Five [8]={B00000000,B01111110,B01000000,B00111100,B00000010,B01000010,B00111100,B00000000};
byte Reverse [8]={B00000000,B01111100,B01000010,B01000010,B01111100,B01000010,B01000010,B00000000};
byte Neutral [8]={B00000000,B01000010,B01100010,B01010010,B01001010,B01000110,B01000010,B00000000};
//const int CLK = D1; // Set the CLK pin connection to the display
//const int DIO = D2; // Set the DIO pin connection to the display
//const uint8_t blank[] = {0x00, 0x00, 0x00, 0x00}; // Declares the value of "blank"
//const uint8_t data[] = {0xff, 0xff, 0xff, 0xff}; // Declares "data" as all segments on
//const uint8_t n[] = // Required segments to display the character "n"
//{
// SEG_C | SEG_E | SEG_G
//};
//const uint8_t r[] = // Required segments to display the character "r"
//{
// SEG_E | SEG_G
//};
//TM1637Display display(CLK, DIO); //set up the 4-Digit Display
// Set AP credentials
#define AP_SSID "E36GearShifter"
#define AP_PASS "owwmyfrickenexpansiontank"
// UDP
WiFiUDP UDP;
IPAddress local_IP(192, 168, 4, 1);
IPAddress gateway(192, 168, 4, 1);
IPAddress subnet(255, 255, 255, 0);
#define UDP_PORT 4210
// UDP Buffer
char packetBuffer[UDP_TX_PACKET_MAX_SIZE];
void setup() {
// Setup TM1637 Display
//display.clear();
//display.setBrightness(7); // Set the diplay to maximum brightness
//display.setSegments(blank); // Clear display
lc.shutdown(0,false);
lc.setIntensity(0,4);
lc.clearDisplay(0);
// Setup LED pin
pinMode(2, OUTPUT);
// Setup serial port
Serial.begin(115200);
Serial.println();
// Begin Access Point
Serial.println("Starting access point...");
WiFi.softAPConfig(local_IP, gateway, subnet);
WiFi.softAP(AP_SSID, AP_PASS);
Serial.println(WiFi.localIP());
// Begin listening to UDP port
UDP.begin(UDP_PORT);
Serial.print("Listening on UDP port ");
Serial.println(UDP_PORT);
}
void loop()
{
// Receive packet
UDP.parsePacket();
UDP.read(packetBuffer, UDP_TX_PACKET_MAX_SIZE);
if (packetBuffer[0] == 0) {
Serial.println("Neutral");
for(int i=0;i<8;i++) lc.setRow(0,i,Neutral[i]);
//lc.setRow(Neutral);
//display.setSegments(n, 1, 3);
}
if (packetBuffer[0] == 1) {
Serial.println("One");
for(int i=0;i<8;i++) lc.setRow(0,i,One[i]);
//lc.setRow(One);
//display.showNumberDec(1, false, 1, 3);
}
if (packetBuffer[0] == 2) {
Serial.println("Two");
for(int i=0;i<8;i++) lc.setRow(0,i,Two[i]);
//lc.setRow(Two);
//display.showNumberDec(2, false, 1, 3);
}
if (packetBuffer[0] == 3) {
Serial.println("Reverse");
for(int i=0;i<8;i++) lc.setRow(0,i,Reverse[i]);
//lc.setRow(Reverse);
//display.setSegments(r, 1, 3);
}
if (packetBuffer[0] == 4) {
Serial.println("Three");
for(int i=0;i<8;i++) lc.setRow(0,i,Three[i]);
//lc.setRow(Three);
//display.showNumberDec(3, false, 1, 3);
}
if (packetBuffer[0] == 5) {
Serial.println("Four");
for(int i=0;i<8;i++) lc.setRow(0,i,Four[i]);
//lc.setRow(Four);
//display.showNumberDec(4, false, 1, 3);
}
if (packetBuffer[0] == 6) {
Serial.println("Five");
for(int i=0;i<8;i++) lc.setRow(0,i,Five[i]);
//lc.setRow(Five);
//display.showNumberDec(5, false, 1, 3);
}
}