
Originally Posted by
MaltWhiskey
Can i have a look at your code somewhere? I’m interested in the communication part between teensy and esp.
MaltWhiskey,
The code is fairly straightforward - it uses serial transmission.
All packets are of this format:
Code:
struct chanNamePktO{ // output channel names
int8_t pktType = PT_ONAMES;
uint8_t groupID; // which controller (multiple sets) is being managed?
char name[OUTCHANS][NAMELEN]; // this is the output channel name
}; //outChan
and they're wrapped in different headers for transmission by UDP or serial.
The serial header is:
Code:
#define PRELEN 4
#define PREAMBLE "MIXX"
struct serialHeader {
char sPreamble[PRELEN] ;
uint8_t crc;
uint16_t pktLen; // no need for a group ID, serial comms is always between an ESP32 controller and a Teensy audio processor
};
the code to synchronise packets is
Code:
// returns length of data read
int getmySerialPkt(universalBuf *bufp)
{
int pktlen;
uint8_t crc;
short int i;
char ch, pre[PRESTRINGLEN] = SERIALPREAMBLE;
serialHeader sh;
char tempBuf[72];
// scan for PREAMBLE using a simple state-variable machine
int8_t foundCh = 0;
int chRead = 0;
if (!mySerial.available())
return PT_NONE;
while (mySerial.available()) // read until no further data available, move to next phase if preamble is found
{
ch = mySerial.read();
if (chRead < 72) tempBuf[chRead] = ch;
chRead++;
if (ch == pre[foundCh])
{
sh.sPreamble[foundCh] = ch; // just for debugging
foundCh++;
}
else
foundCh = 0;
if (foundCh >= PRELEN) // read correct preamble
break;
delayMicroseconds(byteTime); // wait for another byte to get here
for (i = 0; i < SERIALWAITFOR; i++)
if (!mySerial.available())
delayMicroseconds(byteTime); // wait a bit longer, transmit may be interrupted
if (!mySerial.available())
{
Serial.println("GMS header timeout");
return PT_BAD;
}
}
if (foundCh < PRELEN)
{
Serial.println("GMS bad hdr");
mySerial.flush(); // dump the rest of chars in buffer
return PT_BAD; // found no preamble in available data
}
// from here on we know the sizes of data, so use blocking code
// serialTimeout determines the max inter-character gap
// get rest of header
i = mySerial.readBytes((char *)&sh.crc, sizeof(sh)-PRELEN);
if(crc == sh.crc)
{
parseInPkt(bufp, sh.pktLen);
return bufp->pktType;
}
Serial.println("GMS bad CRC");
return PT_BAD;
}
the crc algorithm is a straight crc8, easily obtainable from multiple sources.
The standard serial receive buffer is
Code:
#define RX_BUFFER_SIZE 64
so I buffer input in a much larger on, so that the code doesn't block on larger packets.
There's a trade off between block latency rate and how often you need to service the routine (< 64 bytes at the data rate). I use 115200 quite reliably. Haven't tried higher rates, but there's no reason that they shouldn;t work reliably.
Have fun!
Richard