I didn't understand how pd handles the incoming data
how do you register an object in pd to a specific imput from Arduino?
pd is already based on streams of data, AKA dataflow, so this firmware makes Arduino output the data as fast as it can read it in a stream. Then changing modes, (input, output, PWM, pulseIn) are done using commands, which are like events.
how do you do something like this
val1 = analogRead(pin5)
val2 = digitalRead(pin6)
In a program like Flash that is event-based (like most programming languages), I think I would make an interface similar to how you would get mouse coordinates: send data only when it changes, and then make events for each change. But that would probably be quite a bit of work.
A simple idea for the analogIns would be to make a function that write the value to a variable whenever it receives data from the serial port, then analogRead() would just output that variable. Digital reading is trickier since you are likely going to be using buttons with that. Then its really like an event. If you just poll it with something like digitalRead(), then you might miss a button press.
To start read data from Arduino, you wait for the cycle marker byte: 255. Then you are at the top of the cycle. The next byte is digital pins 0-6, then digital pins 7-14. Then comes byte pairs for each analogIn, which are reassembled to make the 10-bit value. To send digital data to Arduino, its just a 3 byte cycle, 255 for the marker, one by for digital pins 0-6 and the next byte for pins 7-13.
I can understand if you serialize the data coming from Arduino
so that Arduino sends a long "string" or byte-cycle like
255 0 0 0 0 0 0 0 0 0 0 0 0 ?-? ?-? ?-? ?-? ?-?
- 255 is the starting cycle marker
- 6 bytes for digital pin 1->6
- 6 bytes for digital pin 7->14
- 5 pairs(?-?) what do they look like (I have to test it yet)
This is complicated, I did this to make the data format as compact as possible. But its not too bad to use once you get the hang of it. You have to think in terms of bits here. For example, for each byte on the serial port, the 8th bit is used to mark that byte as data or commands. If the 8th bit is 0, that byte is data (0-127 is the range of values then). If the 8th bit is 1, that byte is a command (128-255).
Its actually like this (each element is a byte):
255 pin0-6 pin7-13 aIn0-high aIn0-low aIn1-high aIn1-low aIn2-high aIn2-low
pin0-6 is one byte, 8 bits. The first 7 bits are mapped to digital input pins 0 thru 6. The 8th bit is always 0.
pin7-13 is one byte, 8 bits. The first 7 bits are mapped to digital input pins 7 thru 13. The 8th bit is always 0.
So for these you need to use bit-wise operators to get each pin's value from the byte. For this you would use the bitwise AND: & (note, its not &&). To get the value of the first bit, you would do (inputByte & 1), for the second (inputByte & 2), for the third (inputByte & 4). The second argument is 2 to the power of X, where X is the bit position. Basically, its like an array of bits. So the first bit is (inputByte & (2^0)), so like arrays, the first element is 0.
The analog values also use bitwise techniques to fit 10-bits of data into two separate 8-bit bytes. With the analog data, I just use the first 7-bits and set the 8th bit to 0, to mark that byte as data and not a command.
I build these bytes like this:
printByte(analogData >> 7); // bitshift the big stuff into the output byte
printByte(analogData % 128); // mod by 32 for the small byte
The first one, I take the 16-bit int analogData, and use a >> "right-shift" bitwise operator. This literally moves the bits to the right. So I move the values over 7 bits, so I am now getting the top 7-bits of analogData and output that as a byte.
Then I use % "modulo" 128 to get the bottom 7-bits of analogData and output that as a byte.
Then on the host side, I have to reassemble those two values into a 14-bit value. That is easy: for the first byte, the high byte, I multiply it by 128 (2^7), then I add the second byte. Voila. You know have 14-bits of resolution sent in 8-bit chunks.
This may seem quite complicated, but it has a number of benefits: the data cycle is always two bytes at a time, so you don't have to deal with variable data length. Plus its super compact, so it sends data as quickly as possible. But yes, it makes the programming more complicated. That's why I want to see easy-to-use objects written for other languages, so people don't have to think about these low-level details, but can reap the benefits of really fast data transfer.