My task is to accept data at a speed of 100,000 baud (Futaba S-BUS lib) and sometimes transmit several bytes at a speed of 9600. I conducted many experiments, all of them did not work. For example, today I made a data generator. Boards-Arduino Nano.
void setup() {
Serial.begin(4800);
}
void loop() {
for (byte i = 0; i < 254; i++)
{
Serial.println(i);
delay(5);
}
}
Data Receiver Code.
// Serial Speed Switch test
byte incomingByte = 0; // for incoming serial data
void setup() { }
void loop() {
Serial.begin(4800);
//delayMicroseconds(5000);
if (Serial.available() > 0) {
incomingByte = Serial.read();
}
//delayMicroseconds(5000);
Serial.end ();
//delayMicroseconds(5000);
Serial.begin(19200);
//delayMicroseconds(5000);
Serial.println(incomingByte, DEC);
//delayMicroseconds(5000);
Serial.end ();
delayMicroseconds(5000);
}
Some data is accepted, but despite any changes in delays, it did not work out to achieve the correct result even at these low speeds. Before that, I experimented with the SoftwareSerial library for data transfer. Very high CPU usage.
I came to the disappointing conclusion that switching the speed in the loop does not work correctly!
I would like to know who actually solved such problems?
While I have an idea to make a pseudoSerial Tx generator given on Timer2 and pin manipulating.
I don't see you changing the speed in the transmitter. Before changing the speed you might need to flush the serial, to send out pending bytes in the transmit buffer. This might be done with Serial.begin() or Serial.end(), but I didn't find any information in the documentation. You might need to negotiate the speed change on both sides, e.g. "I am going to change to speed x" -> "Ok, go ahead" -> both partys switch and wait for some time.
Gennady:
sometimes transmit several bytes at a speed of 9600.
I experimented with the SoftwareSerial library for data transfer. Very high CPU usage.
Well yes in some way SoftwareSerial is a blocking protocol for the transmission, but if you send only several bytes at 9600, you can expect to complete the transmission at a little over 1ms p/byte and your input on the hwSerial should not be disturbed by it. If you switch between BAUD rates on the hwSerial for sure you will lose incoming data if any comes in during transmission at the other BAUD rate.
Thank you all for the tips! It helped me find my mistake.
It is necessary to coordinate the reception of one byte and then transfer it. I did differently. I transmit the same byte at a speed of 115200. Then I check the received byte and indicate the error with the help of LED. Then I switch the speed to 9600 and transfer several bytes. This is how it works. Only came to pick up the delay when the transfer is disabled, so that all the bytes have time to be transferred. Receiver code below.
// Serial Speed Switch test
byte incomingByte = 0; // for incoming serial data
void setup()
{
pinMode(13, OUTPUT);
}
void loop()
{
Serial.begin(115200);
if (Serial.available() > 0)
{
incomingByte = Serial.read();
if (incomingByte != 100)
{
digitalWrite(13, HIGH);
delay(100);
digitalWrite(13, LOW);
}
}
Serial.end ();
Serial.begin(9600);
Serial.println("SuperTest");
delayMicroseconds(12000);
Serial.end ();
}
}
LightuC:
I don't see you changing the speed in the transmitter. B
LightuC:
I don't see you changing the speed in the transmitter. Before changing the speed you might need to flush the serial, to send out pending bytes in the transmit buffer. This might be done with Serial.begin() or Serial.end(), but I didn't find any information in the documentation. You might need to negotiate the speed change on both sides, e.g. "I am going to change to speed x" -> "Ok, go ahead" -> both partys switch and wait for some time.
I corrected my mistake! See above. In principle, it works now. I switched the speed correctly. But the received bytes could not be displayed consecutively (from 0 to 255) since during the transfer, the generator had time to run through many bytes. That was my mistake.
Deva_Rishi:
Well yes in some way SoftwareSerial is a blocking protocol for the transmission, but if you send only several bytes at 9600, you can expect to complete the transmission at a little over 1ms p/byte and your input on the hwSerial should not be disturbed by it. If you switch between BAUD rates on the hwSerial for sure you will lose incoming data if any comes in during transmission at the other BAUD rate.
Yes, I understand that there will be a loss of input data. But the SoftwareSerial will so heavily load the CPU that it has strong jitter on the PWM outputs. And I also need them. As far as I know, in version IDE 1.8.2, the NewSWSerial library is used and there are no newer SoftwareSerial libraries? Therefore, I switched to using only the UART HW port. But I would really like to try to make a UART HW TX on Timer 2.But now I do not have enough experience with timers.
Gennady:
As far as I know, in version IDE 1.8.2, the NewSWSerial library is used and there are no newer SoftwareSerial libraries?
have you tried AltSoftSerial.h it limits the pins to 8 & 9 and i think it does disable PWM on pin 10 ? i am not sure about this, but do you understand that if you don't post a complete sketch, we can not always advise you properly.
Deva_Rishi:
have you tried AltSoftSerial.h it limits the pins to 8 & 9 and i think it does disable PWM on pin 10 ? i am not sure about this, but do you understand that if you don't post a complete sketch, we can not always advise you properly.
Thanks for the advice. But my program generates 8 PWM using two timers - T0 (or T2) and T1. Therefore, AltSoftSerial does not suit me. This library uses T1.
As a result of the experiments, I came to the conclusion that the FUTABA_SBUS library does not work if the Loop () method uses turning off and on the UART port. Therefore, it will also not work when switching the UART speed to 9600 and then return to 100000 for sbus.