Gig: Convert SPI data to PWM

We are using an arduino pro mini as a dedicated SPI to PWM converter for a RPI0 controlled Robot. We are sending a constant stream of data and are getting a lot of errors. These errors are causing lag and instability in our PWM controlled steering servo and motor ESC.

We think there could be an issue with the SPI speed setting or our Sketch but not sure.

Looking for someone who could help us with this.

Please contact me via PM or reply if you are interested and qualified to help!

We are sending a constant stream of data

Why? How often does the steering angle or throttle position REALLY need to change?

We think there could be an issue with the SPI speed setting or our Sketch but not sure.

Don't you think posting the sketch might be a good idea?

The commands are sent via UDP so if a single command is lost or delayed for a significant amount of time it could cause a crash.

Sketch attached. :slight_smile:

I am not a (or the) developer but I can pull him in to a discussion if needed.

SPItoPWM_copy.ino (4.17 KB)

Lots of fancy coding and then this beginner's mistake:

ISR(SPI_STC_vect) {
  #ifdef _DEBUG
      Serial.print("Got Data!! ");
      Serial.println(SPDR);
  #endif
  packet.write(SPDR); // grab byte from SPI Data Register
}

This WILL cause problems when you're running it with _DEBUG defined.

Also interesting that there are two #ifdefs for _DEBUG, while there's a DEBUG defined and there are two more #ifdefs that look for DEBUG. Not good for readability, asking for errors to use two so similar variables.

Mauronic:
The commands are sent via UDP so if a single command is lost or delayed for a significant amount of time it could cause a crash.

That is upstream - to the device that then sends the SPI command to the slave (of which you posted the code).

There’s no need to send a stream of SPI commands to the slave. Master receives an UDP command (I assume you do send those continuously to make sure at least one of them arrives), then check whether it’s different from the previous command, and if so send the command (over SPI) to the slave (and have slave ACK this, if you want to be really sure it was received and handled).

Without knowing anything else about your project, I'd say you have an inherently bad design. UDP is not guaranteed at all! UDP packets may be delivered in the "wrong" order or just dropped altogether by the network. I've seen UDP packets over a small internal network be delayed by several seconds frequently.

Unless your design handles these problems properly, you'd be better off using TCP.

Thanks for your responses guys.

wvmarle:
That is upstream - to the device that then sends the SPI command to the slave (of which you posted the code).

There's no need to send a stream of SPI commands to the slave. Master receives an UDP command (I assume you do send those continuously to make sure at least one of them arrives), then check whether it's different from the previous command, and if so send the command (over SPI) to the slave (and have slave ACK this, if you want to be really sure it was received and handled).

Good idea, we will try this.

(According to my developer, we are sending 4 bytes (3 data bytes and 2 CRC-4's in one byte) with no ACK implemented. If the CRC doesn't match we drop the full 4 bytes and wait for the next. We have to drop data about 30% of the time.)

I think you have to take a real hard look at your wiring.

A 30% failure for SPI transmission is 30% higher than you should expect (normal is pretty close to 0%).