2

I am working on communicating 4 switch states across multiple Arduinos using only one pin. It must be as fast as conceivably possible.

Currently I have a master Arduino reading all 4 switches (multiplexing) and encoding them as 4-bit values: 0001 = 0, 0010 = 1, 0011 = 2 and so on up to 1111 = 15. I am thinking of assigning the low and high pulse duration/width, (+1) to produce a PWM square wave. So 1+0=1, 1+1=2, 1+2=3 ... 1+15=16. The high width (or low width) will hold the muxed value (+1.) Each slave would read this muxed value and demux it to get the state of all 4 switches.

Now to my concern: Is this approach safe and reliable? Or should I triple up the values: 1=3, 2=6, 3=9 ... to build in some tolerance and prevent some time misread due to some miss-interpolations? My switches control motors and a misread could have some unpleasant consequences.

I am using the Arduino's internal crystal, nothing external.

As a side note: I am actuality using Seeeduinos XIAO and not an Arduino. I started working on the timer based PWM writing and reading aspect, but it turns out to be quite complicated as there is not a lot of exaples to be found.

MeSo2
  • 177
  • 10
  • 2
    Please define "reliable" in aspects of hardware and software. -- HW: How long are the wires between the reading Arduino and the motor Arduinos? How much interferences do you expect? -- SW: You could use multiple readings in the receivers and a majority decision. -- Radio control servos get their position command by a pulse width, 1 to 2 ms every 20ms. The resolution is 1% or better. Expensive models in delicate conditions (think about high speed airplanes) are controlled by this. So PWM **is** a way with _some reliability_. – the busybee Aug 20 '21 at 06:25
  • 2
    Why not just use Serial? You can use some pretty fast baud rates reliably and you only need 1 wire for transmission only. – Majenko Aug 20 '21 at 08:55
  • 1
    The Arduino PWM output goes from 0 to 255, so you could multiply by 15 for a maximum value of 240 to give a greater margin of error. Though the serial option is better. You could send data packets with CRC/ECC for greater reliability. – tim Aug 20 '21 at 11:23
  • Actually, you could do both PWM and serial. The receivers could compare the two and only act if they agree whilst flagging discrepancies. – tim Aug 20 '21 at 11:35
  • This is presumably for an e-stop? Would you ever want to e-stoo a single motor? Is binary sufficient here? – Dave Newton Aug 20 '21 at 12:00
  • @thebusybee You suggestions are exactly the directions I was heading. Thank you for mentioning interference! All wires are under 8 inches and should be hopefully not too close to anything discharging interference. – MeSo2 Aug 20 '21 at 14:22
  • @Majenko serial is to slow. I want something supper fast. – MeSo2 Aug 20 '21 at 14:24
  • @tim good point. I think I will be multiplying by 6, which will be giving me a 3 point offset in either direction. – MeSo2 Aug 20 '21 at 14:30
  • The ATMega328P is capable of 2MBaud. That's 200,000 potential updates of your switches per second. Is that not "super fast" enough? Most of the slowdown of serial is the Arduino's libraries which are inefficient. Access the UART registers directly for extra speediness. – Majenko Aug 20 '21 at 14:39
  • @DaveNewton It is true that a good portion of the logic is e-stop related. Which now gives me the idea of splitting up some of the logic. I could use a superseding e-stop very short pulse, to obtain a faster read, just when the main motor gets turned on. **This would dramatically speed up things!** – MeSo2 Aug 20 '21 at 14:50
  • @MeSo2 That's the approach I would take, although in fairness, serial should be plenty fast enough. My view of an e-stop is "U STOPS ALL TEH THINGS NOW!" and post-e-stop comms can do whatever it wants. This also allows the e-stop to be tied to an interrupt pin as if each unit had its own e-stop slap switch. Any post-mortem comms can be handled once the unit is in the e-stop state. – Dave Newton Aug 20 '21 at 14:57
  • @MeSo2 While I haven't tried anything like this for CNC/life-threatening-car-like-things, I have done it with robots using separate control modules, w/ serial protocols. High-priority msgs were handled *extremely* quickly, w/ e-stop equivalents handled in <1-2ms (500/sec). For comparison, the SawStop stops in ~5ms (200/sec), airbag deploys are ~50ms (20/sec). – Dave Newton Aug 20 '21 at 15:07
  • 1
    @Majenko _Access the UART registers directly_ ... I did not know you can do that with serial. Having to learn about timers was taxing as is; not sure if I have it in me to learn about UART registers. – MeSo2 Aug 20 '21 at 15:16
  • In my opinion your timer approach has no benefits over using UART like majenko suggested. If it has to be fast you'd have to measure pulse lengths with high precision and it costs CPU time - even if you use interrupts. – Sim Son Aug 25 '21 at 11:56

0 Answers0