A
Arduino3d ago
wtf

Serial communication between ESP8266 and Nano not in sync or corrupted

I'm driving a 16x8 led matrix using the arduino nano and implemented it so that it receives display data through serial (16 bytes per frame). when sending the data through web serial everything works perfectly, but when I hook up an ESP8266 everything goes south. here's my code:
5 Replies
wtf
wtfOP3d ago
arduino nano
#include <Arduino.h>
#include <SPI.h>

#define NUM_ROWS 8
uint16_t matrix[NUM_ROWS] = {0};
uint8_t curRow = 0;

const int LATCH_PIN = 10;
const int OE_PIN = 9;

void setupTimer()
{
// https://www.8bit-era.cz/arduino-timer-interrupts-calculator.html
// TIMER 1 for interrupt frequency 8000 Hz:
cli(); // stop interrupts
TCCR1A = 0; // set entire TCCR1A register to 0
TCCR1B = 0; // same for TCCR1B
TCNT1 = 0; // initialize counter value to 0
// set compare match register for 8000 Hz increments
OCR1A = 1999; // = 16000000 / (1 * 8000) - 1 (must be <65536)
// turn on CTC mode
TCCR1B |= (1 << WGM12);
// Set CS12, CS11 and CS10 bits for 1 prescaler
TCCR1B |= (0 << CS12) | (0 << CS11) | (1 << CS10);
// enable timer compare interrupt
TIMSK1 |= (1 << OCIE1A);
sei(); // allow interrupts
}

void setup()
{
pinMode(OE_PIN, OUTPUT);
digitalWrite(OE_PIN, HIGH);

pinMode(LATCH_PIN, OUTPUT);
digitalWrite(LATCH_PIN, HIGH);

SPI.begin();
SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE0));
setupTimer();

Serial.begin(9600);
}

void loop()
{
if (Serial.available())
{
Serial.readBytes((uint8_t *)matrix, NUM_ROWS * sizeof(uint16_t));
}
}

static inline uint8_t reverse8(uint8_t b)
{
b = (b & 0xF0) >> 4 | (b & 0x0F) << 4;
b = (b & 0xCC) >> 2 | (b & 0x33) << 2;
b = (b & 0xAA) >> 1 | (b & 0x55) << 1;
return b;
}

ISR(TIMER1_COMPA_vect)
{
uint8_t rowByte = (1 << curRow);
uint8_t colA = (matrix[curRow] >> 8) & 0xFF;
uint8_t colB = matrix[curRow] & 0xFF;

PORTB |= (1 << PB1); // Disable output
PORTB &= ~(1 << PB2);
SPI.transfer(reverse8(colB)); // Region B SR
SPI.transfer(reverse8(colA)); // Region A SR
SPI.transfer(rowByte); // Row multiplexing SR
PORTB |= (1 << PB2);
PORTB &= ~(1 << PB1); // Re-enable output`

curRow++;
if (curRow >= NUM_ROWS)
curRow = 0;
}
#include <Arduino.h>
#include <SPI.h>

#define NUM_ROWS 8
uint16_t matrix[NUM_ROWS] = {0};
uint8_t curRow = 0;

const int LATCH_PIN = 10;
const int OE_PIN = 9;

void setupTimer()
{
// https://www.8bit-era.cz/arduino-timer-interrupts-calculator.html
// TIMER 1 for interrupt frequency 8000 Hz:
cli(); // stop interrupts
TCCR1A = 0; // set entire TCCR1A register to 0
TCCR1B = 0; // same for TCCR1B
TCNT1 = 0; // initialize counter value to 0
// set compare match register for 8000 Hz increments
OCR1A = 1999; // = 16000000 / (1 * 8000) - 1 (must be <65536)
// turn on CTC mode
TCCR1B |= (1 << WGM12);
// Set CS12, CS11 and CS10 bits for 1 prescaler
TCCR1B |= (0 << CS12) | (0 << CS11) | (1 << CS10);
// enable timer compare interrupt
TIMSK1 |= (1 << OCIE1A);
sei(); // allow interrupts
}

void setup()
{
pinMode(OE_PIN, OUTPUT);
digitalWrite(OE_PIN, HIGH);

pinMode(LATCH_PIN, OUTPUT);
digitalWrite(LATCH_PIN, HIGH);

SPI.begin();
SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE0));
setupTimer();

Serial.begin(9600);
}

void loop()
{
if (Serial.available())
{
Serial.readBytes((uint8_t *)matrix, NUM_ROWS * sizeof(uint16_t));
}
}

static inline uint8_t reverse8(uint8_t b)
{
b = (b & 0xF0) >> 4 | (b & 0x0F) << 4;
b = (b & 0xCC) >> 2 | (b & 0x33) << 2;
b = (b & 0xAA) >> 1 | (b & 0x55) << 1;
return b;
}

ISR(TIMER1_COMPA_vect)
{
uint8_t rowByte = (1 << curRow);
uint8_t colA = (matrix[curRow] >> 8) & 0xFF;
uint8_t colB = matrix[curRow] & 0xFF;

PORTB |= (1 << PB1); // Disable output
PORTB &= ~(1 << PB2);
SPI.transfer(reverse8(colB)); // Region B SR
SPI.transfer(reverse8(colA)); // Region A SR
SPI.transfer(rowByte); // Row multiplexing SR
PORTB |= (1 << PB2);
PORTB &= ~(1 << PB1); // Re-enable output`

curRow++;
if (curRow >= NUM_ROWS)
curRow = 0;
}
ESP8266:
#include <Arduino.h>

uint16 buffer[] = {
0b1000000000000001,
0b0100000000000010,
0b0010000000000100,
0b0001000000001000,
0b0000100000010000,
0b0000010000100000,
0b0000001001000000,
0b0000000110000000,
};

void setup()
{
Serial1.begin(9600);
}

void loop()
{
delay(2000);
for (int i = 0; i < 8; i++)
{
Serial1.print((uint8_t)buffer[i] & 0xFF);
Serial1.print((uint8_t)((buffer[i] >> 8) & 0xFF));
}
}
#include <Arduino.h>

uint16 buffer[] = {
0b1000000000000001,
0b0100000000000010,
0b0010000000000100,
0b0001000000001000,
0b0000100000010000,
0b0000010000100000,
0b0000001001000000,
0b0000000110000000,
};

void setup()
{
Serial1.begin(9600);
}

void loop()
{
delay(2000);
for (int i = 0; i < 8; i++)
{
Serial1.print((uint8_t)buffer[i] & 0xFF);
Serial1.print((uint8_t)((buffer[i] >> 8) & 0xFF));
}
}
wtf
wtfOP3d ago
supposed to be a V shape but I get garbage instead
wtf
wtfOP3d ago
I'm certain it's not a hardware issue since I have tested serial communication from the esp to nano beforehand with one wire going from the esp's TX1 -> nano's RX and a common ground and everything worked fine
wtf
wtfOP2d ago
turns out I had to use Serial.write instead of print 🤦🏻‍♂️
No description
wtf
wtfOP2d ago
there goes a whole day of debugging

Did you find this page helpful?