Problems with Teensy 3.6 Serial2 Tx buffers.

Status
Not open for further replies.

sw_hunt

Well-known member
I think I have increased the Tx buffer size for Serial2 but when I run Serial2.availableForWrite() it still shows the small value.

I'm having serial midi problems with a Sequential synth occasionally receiving corrupted data, so I'm trying to increase the Tx buffer to see if this will help. I've changed SERIAL2_TX_BUFFER_SIZE from 40 to 512 in Serial1.c and Serial2.c in ...avr/cores/teensy3 and recompiled. The problem is still there and when I repeatedly run Serial2.availableForWrite() it still shows 39.

Serial2.c
////////////////////////////////////////////////////////////////
// Tunable parameters (relatively safe to edit these numbers)
////////////////////////////////////////////////////////////////

#ifndef SERIAL2_TX_BUFFER_SIZE
#define SERIAL2_TX_BUFFER_SIZE 512 // number of outgoing bytes to buffer was 40
#endif
#ifndef SERIAL2_RX_BUFFER_SIZE
#define SERIAL2_RX_BUFFER_SIZE 512 // number of incoming bytes to buffer was 64
#endif
#define RTS_HIGH_WATERMARK (SERIAL2_RX_BUFFER_SIZE-24) // RTS requests sender to pause
#define RTS_LOW_WATERMARK (SERIAL2_RX_BUFFER_SIZE-38) // RTS allows sender to resume
#define IRQ_PRIORITY 64 // 0 = highest priority, 255 = lowest

Have I not increased the buffer size correctly or am I not reading or interpreting the reported value correctly?

Would increasing the Tx buffer size help me anyway? All transmitted messages come from the Teensy so I'm not concerned with incoming messages. I'm generating midi CCs in the Teensy 3.6 from an LFO and from an interrupt driven clock. IF the Tx buffer does fill up then I thought the Teensy would just halt until it's free again and then continue? Do the interrupt driven clocks mess with this and cause corruption?

Test program compiled (I believe) using the Serial2.c changes above, showing the clock function I use:

Code:
#include <uClock.h>
#include <SD.h>
#include <EEPROM.h>
#include <ResponsiveAnalogRead.h> //  https://github.com/dxinteractive/ResponsiveAnalogRead
#include <Adafruit_CharacterOLED.h>//include the OLED library 
#define SD_CS BUILTIN_SDCARD // if compile fails here it's because you've installed the standards SD library and compiler is using that instead of Teensy one.  Delete the standard one's folder
const int versionVersion = 2; const int versionMajor = 0; const int versionMinor = 29;
const int errorReporting = 0;
Adafruit_CharacterOLED lcd(OLED_V2, 2, 3, 4, 5, 6, 7, 8); // 2004 OLED!
// GND (pin 1) to GND * VDD (pin 2) to 5V * RS (pin4) to digital pin 2 * R/W (pin 5) to digital pin 3 * Enable (pin 6) to digital pin 4 * D4 (pin 11) to digital pin 5 * D5 (pin 12) to digital pin 6 * D6 (pin 13) to digital pin 7 * D7 (pin 14) to digital pin 8
Sd2Card card;
#define MIDI_CLOCK 0xF8
#define MIDI_START 0xFA
#define MIDI_STOP  0xFC
const float snapMultiplier = 0.003; const bool responsiveSleep = true; // previously 0.005
ResponsiveAnalogRead analog [] {{A0, responsiveSleep, snapMultiplier}, {A1, responsiveSleep, snapMultiplier}, {A2, responsiveSleep, snapMultiplier}, {A3, responsiveSleep, snapMultiplier}, {A4, responsiveSleep, snapMultiplier}, {A5, responsiveSleep, snapMultiplier}, {A6, responsiveSleep, snapMultiplier}, {A7, responsiveSleep, snapMultiplier}, {A8, responsiveSleep, snapMultiplier}, {A9, responsiveSleep, snapMultiplier}, {A10, responsiveSleep, snapMultiplier}, {A11, responsiveSleep, snapMultiplier}, {A12, responsiveSleep, snapMultiplier}, {A13, responsiveSleep, snapMultiplier}, {A14, responsiveSleep, snapMultiplier}, {A15, responsiveSleep, snapMultiplier}, {A16, responsiveSleep, snapMultiplier}, {A17, responsiveSleep, snapMultiplier}, {A18, responsiveSleep, snapMultiplier}, {A19, responsiveSleep, snapMultiplier}, {A20, responsiveSleep, snapMultiplier}};
elapsedMillis steveTimer1;
const int switchPins[] = {30, 11}; // prototype v2 was 9,11     v3 is 30,11
const int ledPins[] = {13, 12};
const int muxE = 24, muxS0 = 25, muxS1 = 26, muxS2 = 27, mux1out = 28, mux2out = 29;

void setup() {
  Serial.begin(9600);//diagnostic serial port
  Serial1.begin(31250); //In 1 and Thru
  Serial2.begin(31250); //In2 and Out
  delay(100);
  Serial.println("Starting...");

  pinMode(switchPins[0], INPUT_PULLUP); pinMode(switchPins[1], INPUT_PULLUP); pinMode(ledPins[0], OUTPUT); pinMode(ledPins[1], OUTPUT);
  pinMode(muxE, OUTPUT); pinMode(muxS0, OUTPUT); pinMode(muxS1, OUTPUT); pinMode(muxS2, OUTPUT); pinMode(mux1out, INPUT_PULLUP); pinMode(mux2out, INPUT_PULLUP);
  uClock.init();
  // Set the callback function for the clock output to send MIDI Sync message.
  uClock.setClock96PPQNOutput(ClockOut96PPQN);
  int clockTempo = 120; 
  uClock.setTempo(clockTempo);
}

void loop() {
  if (steveTimer1 >= 10){
    Serial.print("availableForWrite: ");
    Serial.println(Serial2.availableForWrite());
    steveTimer1 = steveTimer1 -10;
  }
}

// The callback function wich will be called by Clock each Pulse of 96PPQN clock resolution.
void ClockOut96PPQN(uint32_t * tick) {
        Serial2.write(MIDI_CLOCK);
}
Thanks :)
 
That looks to be the needed change in what looks to be the correct file.

Unless there are multiple copies of TeensyDuino installed and the edit was not made in the location used? Or for some reason the file change was not seen and not recompiled with the change.

Easy way to test that is to purposefully edit in a syntax error - save the file and rebuild. It should error as expected on that line - like:
Code:
////////////////////////////////////////////////////////////////
// Tunable parameters (relatively safe to edit these numbers)
////////////////////////////////////////////////////////////////

[B][COLOR="#FF0000"]xyz doesn't go here !!! [/COLOR]#ifndef SERIAL2_TX_BUFFER_SIZE[/B]
#define SERIAL2_TX_BUFFER_SIZE 512 // number of outgoing bytes to buffer was 40

If that causes a build error the file was recompiled - remove the error and rebuild to see the results.
 
Thanks, good idea. The compiler reported:

C:\Program Files (x86)\Arduino\hardware\teensy\avr\cores\teensy3\serial2.c:39:1: error: unknown type name 'xyz'

So I removed your comment, saved, recompiled and still get the small buffer size reported! availableForWrite: 39

Very strange
 
The latest core library code, which is currently only on github, supports addMemoryForWrite() on Teensy 3.x, thanks to Kurt!

With this feature you no longer need to edit the core library. You can just allocate a static buffer and pass it to Serial2.addMemoryForWrite().

Code:
unsigned char serial2buffer[1000];

void setup() {
  while (!Serial); // wait for Arduino Serial Monitor
  Serial.println("Serial2 Buffer Size Test");
  Serial2.begin(9600);
  Serial.print("Serial2.availableForWrite before adding buffer: ");
  Serial.println(Serial2.availableForWrite());
  Serial2.addMemoryForWrite(serial2buffer, sizeof(serial2buffer));
  Serial.print("Serial2.availableForWrite after adding buffer: ");
  Serial.println(Serial2.availableForWrite());
}

void loop() {
}

I should probably package up a 1.54-beta6 installer soon....
 
FWIW, I just tested editing serial2.c in Arduino 1.8.13 with Teensyduino 1.54-beta5. I changed SERIAL2_TX_BUFFER_SIZE to 512. Indeed Serial2.availableForWrite() returns 511.

I can't explain why it's not working for you. It definitely works when I try here. Admittedly, I've using Linux, but I'm pretty sure it's the same on Windows.

But the long-term solution will be Serial2.addMemoryForWrite() in version 1.54, rather than editing the core library files.
 
Thanks Paul (and Kurt!), I'm now reporting availableForWrite: 1039

I'm still getting corruption though...
Anyone got any thoughts on this other part of my question:
Would increasing the Tx buffer size help me anyway? All transmitted messages come from the Teensy so I'm not concerned with incoming messages. I'm generating midi CCs in the Teensy 3.6 from an LFO and from an interrupt driven clock. IF the Tx buffer does fill up then I thought the Teensy would just halt until it's free again and then continue? Do the interrupt driven clocks mess with this and cause corruption?
 
Correction, this has made the corruption a LOT worse! The receiving synth is now getting scrambled parameters within a few seconds of sending midi to it.
 
Status
Not open for further replies.
Back
Top