Tazzi wrote: Mon Oct 25, 2021 1:20 am
...
Is it possible to have serial ports with two different RX/TX buffers?
...
It is considered (by me) to be bad form to modify core code (sorry ag123).
It is better IMO to simply double-buffer the serial stream where you require a larger buffer.
Code: Select all
Serial1 with SERIAL_RX_BUFFER_SIZE = 64bytes and SERIAL_TX_BUFFER_SIZE = 64bytes
Serial2 with SERIAL_RX_BUFFER_SIZE = 512ytes and SERIAL_TX_BUFFER_SIZE = 512bytes
So, in your case, you have a few options to implement, but you can sub-class serial #2 and add a secondary buffer. Or, since you are not servicing Serial2 frequently, you could use SoftwareSerial for the second serial port. Lady Ada has a nice example of subclassing the serial Rx
here.
Adafruit has rewritten most of their libs ... can be a bit difficult to analyze. The "old" code looked like this:
Code: Select all
#include <Arduino.h>
#ifndef _ADAFRUIT_GPS_H
#define _ADAFRUIT_GPS_H
#include <SoftwareSerial.h>
#define MAXWAITSENTENCE 5
class Adafruit_GPS {
public:
void begin(uint16_t baud);
Adafruit_GPS(SoftwareSerial *ser);
char *lastNMEA(void);
boolean newNMEAreceived();
void common_init(void);
void sendCommand(char *);
void pause(boolean b);
boolean parseNMEA(char *response);
uint8_t parseHex(char c);
char read(void);
boolean parse(char *);
void interruptReads(boolean r);
boolean wakeup(void);
boolean standby(void);
uint8_t hour, minute, seconds, year, month, day;
uint16_t milliseconds;
char lat, lon, mag;
boolean fix;
uint8_t fixquality, satellites;
boolean waitForSentence(char *wait, uint8_t max = MAXWAITSENTENCE);
private:
boolean paused;
uint8_t parseResponse(char *response);
SoftwareSerial *gpsSwSerial;
};
#endif
Code: Select all
#include "Adafruit_GPS.h"
#define MAXLINELENGTH 120
volatile char line1[MAXLINELENGTH];
volatile char line2[MAXLINELENGTH];
volatile uint8_t lineidx=0;
volatile char *currentline;
volatile char *lastline;
volatile boolean recvdflag;
volatile boolean inStandbyMode;
boolean Adafruit_GPS::parse(char *nmea) {
if (nmea[strlen(nmea)-4] == '*') {
uint16_t sum = parseHex(nmea[strlen(nmea)-3]) * 16;
sum += parseHex(nmea[strlen(nmea)-2]);
for (uint8_t i=1; i < (strlen(nmea)-4); i++) {
sum ^= nmea[i];
}
if (sum != 0) {
}
}
if (strstr(nmea, "$GPRMC")) {
char *p = nmea;
p = strchr(p, ',')+1;
float timef = atof(p);
uint32_t time = timef;
hour = time / 10000;
minute = (time % 10000) / 100;
seconds = (time % 100);
milliseconds = fmod(timef, 1.0) * 1000;
p = strchr(p, ',')+1;
p = strchr(p, ',')+1;
p = strchr(p, ',')+1;
p = strchr(p, ',')+1;
p = strchr(p, ',')+1;
p = strchr(p, ',')+1;
p = strchr(p, ',')+1;
p = strchr(p, ',')+1;
uint32_t fulldate = atof(p);
day = fulldate / 10000;
month = (fulldate % 10000) / 100;
year = (fulldate % 100);
return true;
}
return false;
}
char Adafruit_GPS::read(void) {
char c = 0;
if (paused) return c;
if(!gpsSwSerial->available()) return c;
c = gpsSwSerial->read();
if (c == '$') {
currentline[lineidx] = 0;
lineidx = 0;
}
if (c == '\n') {
currentline[lineidx] = 0;
if (currentline == line1) {
currentline = line2;
lastline = line1;
} else {
currentline = line1;
lastline = line2;
}
lineidx = 0;
recvdflag = true;
}
currentline[lineidx++] = c;
if (lineidx >= MAXLINELENGTH)
lineidx = MAXLINELENGTH-1;
return c;
}
Adafruit_GPS::Adafruit_GPS(SoftwareSerial *ser)
{
common_init();
gpsSwSerial = ser;
}
void Adafruit_GPS::common_init(void) {
gpsSwSerial = NULL;
recvdflag = false;
paused = false;
lineidx = 0;
currentline = line1;
lastline = line2;
hour = minute = seconds = year = month = day = fixquality = satellites = 0;
milliseconds = 0;
}
void Adafruit_GPS::begin(uint16_t baud) {
if(gpsSwSerial) gpsSwSerial->begin(baud);
delay(10);
}
boolean Adafruit_GPS::newNMEAreceived(void) {
return recvdflag;
}
void Adafruit_GPS::pause(boolean p) {
paused = p;
}
char *Adafruit_GPS::lastNMEA(void) {
recvdflag = false;
return (char *)lastline;
}
uint8_t Adafruit_GPS::parseHex(char c) {
if (c < '0')
return 0;
if (c <= '9')
return c - '0';
if (c < 'A')
return 0;
if (c <= 'F')
return (c - 'A')+10;
}
boolean Adafruit_GPS::waitForSentence(char *wait4me, uint8_t max) {
char str[20];
uint8_t i=0;
while (i < max) {
if (newNMEAreceived()) {
char *nmea = lastNMEA();
strncpy(str, nmea, 20);
str[19] = 0;
i++;
if (strstr(str, wait4me))
return true;
}
}
return false;
}