0

tl;dr on on digital ouput/input I would like to communicate with a 1-wire device, whose protocol requires precision to ~15 microseconds. My question is if Arduino Uno's serial communication can be as quick as to support to map the digital pin via serial->USB to my host computers app which should implement the 1-wire protocol?

long version The mode in which I thought to use my Arduino was, to attach it to a host computer and run the logic of what should be done on the host computer, having the Arduino only receive the data (for the pins) and return the state of the pins.

The challenge which prompts me to this question is that the Serial communication is not really that quick, compared to the timing requirement of some protocols (e.g. 1 wire) I wish to implement.
For example: 1-wire-protocol's timing requirements (i.e. range of micorseconds) could easily be kept from code running on the Arduino Uno's Atmega328 directly, which at 16Mhz and assumed 2 cycles per command would allow somewhat a resolution of 2/16Mhz = 0,125 us.

If alternatively the data/instruction for the 1-wire protocol should be mapped via the serial interface to an application running on an PC attached to the Arduino I wonder if the time requirements of the 1-wire protocal can be reached?

It boils down to a question if the Serial communication can have a temporal granularity as small as the about 1 to 15 microseconds needed to implement the 1-wire protocol - not within arduino itself - but in the attached PC's application.

1

Ok, so there's two issues at stake here.

  1. Can the Arduino generate a 1-wire protocol with enough accuracy?
  2. Can you transfer the data fast enough through the UART to tell it to do that generation?

You can't just stream a 1-wire protocol through serial and expect it to work. The low-level serial protocol would very much get in the way. So you have to send instructions to the Arduino to say "Raise the IO pin" and "Lower the IO pin" and "Tell me when the IO pin changes level", and "Set the IO pin to input" etc.

Each of those actions would be a discrete item that you would have to send. Given that you could have a single byte per action (send "I" for set to input, send "O" for set to output, send "L" for set to low, etc - Arduino sends "H" if the pin goes high, or "L" if it goes low, etc), what kind of response could you expect?

Well, at 8 bits + start + stop per byte (so 10 bits) at a good fast rate (say 1MBaud), you would expect one byte to take (1/(1000000/10) = 0.00001s (10µs) to transfer. That's raw transfer speed. On top of that you then have to add the processing of that incoming data - the Arduino adds it to a circular buffer to allow your sketch to read it, and that takes time, and your program then interpreting it, you could expect a latency of say 15µs. At maximum stream rate (no breaks between characters being sent at all) you would have a basic granularity of 10µs (processing the last incoming character while the next one is being received).

That's not counting any other factors such as the UART buffers on your computer, latency before the character even gets to the USB port's endpoint, etc.

So all in all there might be a slim chance that you could do it, but it would be very slim and not easy to achieve a stable result.

Far better would be to implement the 1-Wire protocol on the Arduino and just send/receive the control information to tell it to go ahead and do the work and return the results. After all, that's what the Arduino is designed for - low level interfacing like that.

| improve this answer | |
  • I was fearing as much. I do loath somewhat to implement anything on the Arduino itself, because its limitations with multitasking, ideally I would have simply done the heavilifting on a PC and abuse Arduino via Serial simply as a way to set/get the pins (somewhat in bitflash or firmata style). your answer was helpful. – humanityANDpeace Sep 12 '15 at 18:01
1

Your idea seems wrong-headed, if I may say so without giving offence.

The Arduino is quite capable of generating 1-wire protocol. It certain reads it easily enough with bit-banging.

Trying to send down HLHLHHHLL through serial because your PC is "more powerful" is just not the right way of doing it. Next you'll be wanting to generate PWM on the PC and have the Arduino relay it to an output pin.

Remember, the Arduino (Uno) runs at 16 MHz. The original IBM PC ran at 4.77 MHz (if I remember correctly) so you can regard the Arduino as being as powerful as an early PC.

The simple solution is to send from the PC the data you actually want communicated by 1-wire, and let the Arduino do the actual bit-banging.

| improve this answer | |
  • You suggest well and I do appreciate Arduino and the Atmega328. Yet I think the IBM PC had longer registers (less cycles whenever 16bit/32bit.... calculations where done) and most importantly no 2000 Byte ram, which makes attempts to schedule multitasking and implementing bigger things, challenging for people not yet as good in reducing memory as me. thank you – humanityANDpeace Sep 13 '15 at 7:13
1

It certainly is possible for an Arduino to do this. For example, source code for Atmel's implementations of 1-Wire protocol via bit-banging, via polling UART, and via interrupt-driven UART, is available at github.com.

There is a 21-page PDF file, doc2579.pdf, available at Atmel. It documents how the different implementations work.

However, the notion of communicating faster than serial via the 1-Wire protocol seems like a mistaken notion. As I understand it, the serial implementations above use one serial character per 1-Wire bit, so necessarily are slower than serial.

| improve this answer | |
  • thank you for the encouragement. After some research the numbers I figured were. Highest speed of Serial from Arduino Uno Rev3 is 2,000,000 bits per second, which means that a bit takes about 500nanosecs. Becoming available in a package of 1 Byte means 8*500=4us. For my intented purpose it would need to work with packages for PORT(B,C,D) and DDR(B,C,D) and PIN(B,C,D) send back, which meant 9 bytes per interaction (forwarding PC-app to Arduino) and would be (ignoring yet any CRC overhead) at 9*8*500ns=36us and by this breaking the 1-wire required max 15us for sending a logical 1. – humanityANDpeace Sep 13 '15 at 7:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.