receiving from USB every 10 milliseconds and output to pins at 2 milliseconds?

hi all, i try to get this code to work properly on my Arduino Uno:

/*
  Reading a serial ASCII-encoded string.

 This sketch demonstrates the Serial parseInt() function.
 It looks for an ASCII string of comma-separated values.
 It parses them into ints, and uses those to fade values.


 created 13 Apr 2012
 by Tom Igoe

 modified for 3 values
 send in 5 lines of ascii every 10ms
 3 values for the limit of 64 bytes
 by Newk 2014


 This example code is in the public domain.
 */

// declaring pins:
const int pin09 = 9;
const int pin10 = 10;
const int pin11 = 11;

void setup() {
  // initialize serial:
  Serial.begin(38400);
  // make the pins outputs:
  pinMode(pin09, OUTPUT);
  pinMode(pin10, OUTPUT);
  pinMode(pin11, OUTPUT);
}

void loop() {
  // if there's any serial available, read it:
  while (Serial.available() > 0) {
    // look for the newline. That's the begin of your data:
    if (Serial.read() == '\n') {
      // look for the next 3 valid integer in the incoming serial stream
      // and check for carrige return to set the pins 
      // delay then go to the next 3
      // do it 5 times:
      int val09 = Serial.parseInt();
      int val10 = Serial.parseInt();
      int val11 = Serial.parseInt();      
      if (Serial.read() == '\r') {
        analogWrite(pin09, val09); // set the values to the pins
        analogWrite(pin10, val10);
        analogWrite(pin11, val11);
        delay(2);
        
        int val09 = Serial.parseInt();
        int val10 = Serial.parseInt();
        int val11 = Serial.parseInt();      
        if (Serial.read() == '\r') {
          analogWrite(pin09, val09);
          analogWrite(pin10, val10);
          analogWrite(pin11, val11);
          delay(2);
          
          int val09 = Serial.parseInt();
          int val10 = Serial.parseInt();
          int val11 = Serial.parseInt();      
          if (Serial.read() == '\r') {
            analogWrite(pin09, val09);
            analogWrite(pin10, val10);
            analogWrite(pin11, val11);
            delay(2);
            
            int val09 = Serial.parseInt();
            int val10 = Serial.parseInt();
            int val11 = Serial.parseInt();      
            if (Serial.read() == '\r') {         
              analogWrite(pin09, val09);
              analogWrite(pin10, val10);
              analogWrite(pin11, val11);
              delay(2);
              
              int val09 = Serial.parseInt();
              int val10 = Serial.parseInt();
              int val11 = Serial.parseInt();      
              if (Serial.read() == '\r') {
                analogWrite(pin09, val09);
                analogWrite(pin10, val10);
                analogWrite(pin11, val11);
                delay(2);
              }
            }
          }
        }  
      }  
    }
  }
}

I made a FlowStone patch that sends out ascii values of 60bytes max every 10milliseconds but the results on the flickering LEDs are irregular when i input regular values, so i'm doing something wrong here.

Maybe i should send hex instead of ascii but i am not sure how to write code for that.. but i definitly want that as i could control the values of all 6 PWM outputs within the 64bytes bandwidth (?). But it needss to be stable first. Anyone know what i am doing wrong here?

cheers!

ehm.. i just revisited my patch and the sends to arduino seem fine.. the irregularness where the data send to FlowStone from FL Studio parameters i'm afraid.. so i have to ask them for support on this...

But my question on how to convert this Sketch from ASCII to HEX still stands. To elaborate more on the question:

I would like to send it in strings like above but i dont know if it is possible in hex to let arduino distinguish a newline and carrige return byte from a data one. As newline would be "0A" and carrige return would be "0D" in hex wich would be equivalent to certain values i would like to send to the PWM pins. The only solution i could come up for this problem is to take one of the top brightness of 255 (FF) and use that as a terminator.

Ah, there is one problem with my code that causes irregular behaviour: If i send a string every 10ms like: "\n0,0,0\r0,0,0\r0,0,0\r0,0,0\r255,0,0\r" the LED wil stay lit much longer (allmost permanent) other then: "\n0,0,0\r0,0,0\r0,0,0\r255,0,0\r0,0,0\r" wich behaves as expected.

:fearful: please help!

Sending data as Hex characters won't make any difference, they still have to be converted to byte values before analogWrite() can use them.

Simplest thing is just to send bytes to the Arduino and then there is no need for any of the parseInt() stuff.

If you want to update the LEDs more often than you receive data from the PC you will need to separate the reception from the LED updates. So, for example, if the PC sends enough data for 5 updates the LEDs can be updated 5 times for every package of data received.

I wrote a demo sketch that shows how to transfer byte values between a PC and an Arduino here http://forum.arduino.cc/index.php?topic=225329.0

...R

Hello Robin2, Thank you for responding and your experience!

Sending data as Hex characters won't make any difference, they still have to be converted to byte values before analogWrite() can use them.

Well sending less bytes by converting the ascii to hex (bytes) before sending over usb would lessen the traffic i guess, right? So i understand from what you said, if we would do an integer (ascii) value to the analogWrite() function it would automaticly do a conversion to bytes? Or the bytes where never converted to begin with upon arrival and is just in the IDE for us to read so?

If you want to update the LEDs more often than you receive data from the PC you will need to separate the reception from the LED updates. So, for example, if the PC sends enough data for 5 updates the LEDs can be updated 5 times for every package of data received.

I wrote a demo sketch that shows how to transfer byte values between a PC and an Arduino here http://forum.arduino.cc/index.php?topic=225329.0

This is exacly what i was trying to achieve! As there is a limit of 100 times a second for sending data i came up with this (sort of buffering) to fill in the gaps. Hopefully i will understand your code without understanding python.. as i try to understand what you mean by "markers" in the comments of your code... What i do sort of understand is that you measure the amount of bytes received and if the starting and ending bytes match up or something like that. Cheers!

PS: Any idea why the last string read in my code loop is diffrent then the other strings? I even tried the code without detecting NewLine (\n) and it still behaves that way.

The start and end markers are just two bytes that will never occur in the actual data. The Arduino discards all it receives until it detects the start marker and then it saves everything until it detects the end marker.

Adding in the number of bytes is just an additional assurance that all the data was received - its not essential.

My demo code is designed so it can send every byte value from 0 to 255. It uses the byte values of 254 and 255 as the start and end markers so they can't be included in the code. For that reason it treats 253 as a special byte and values of 253, 254 and 255 are transmitted as pairs of bytes - 253 0, 253 1 and 253 2.

If you don't need to send every byte value the code can be simplified.

I haven't suggested how to update the leds more frequently than the data is received so as not to confuse matters. If you want to discuss that when you have the data transfer working properly I will try to help.

...R

Could you please elaborate on what you mean by sending the start, stop and special byte in pairs? And how your code expects a string of bytes to be formatted.. i had difficulties finding out where in the send string it expects the special byte. Starting the string of bytes with 254 and ending it with 255.. does 253 come right after the first or before the last? Or does this only work with pairing these indicator-bytes up with with the special byte. Still confusing to a beginner like me. Maybe this could be explained on the thread where you posted your democode so it can be used without ruby or java.

As for the data thats being send to your code, does it store its contence untill next completed transmission or does it only count the amount of bytes for the demo? If for the latter i guess i have to incorporate something like the SerialEvent() example and another to get values from that string to the right places.

The way of refining refreshrate of values beyond 10ms has indeed to wait untill this gets sorted.

cheers!

First off the extra complication of the 253 is only necessary if your data must include the values 254 or 255 which would be confused with the start or end markers. If your data will never include 254 or 255 just ignore this concept.

In order to be able to include the values 254 and 255 I decided also to make special use of 253.

When the transmitting code finds a value of 253, 254 or 255 in the data it is being asked to send it replaces (for example) 254 with a pair of bytes 253 and 1.

When the receiving code discovers a 253 in the data it knows that it should be converted into something else by adding it to the next byte. So (using the same example) if it finds 253 it adds it to 1 giving 254 thus converting the pair of bytes back into the single byte 254.

The 253 byte (followed by a 0, 1 or 2) will appear anywhere in the message where there would otherwise have been a 253, 254 or 255.

I hope that makes sense.

In the Python code there is a function sendToArduino(). You pass the data you want to send as a parameter. For example sendToArduino("The stuff I want to send") and the start and end markers etc are added behind the scenes.

On the Arduino side the received data appears in the global variable "dataRecvd" and the data you want the Arduino to send is put into the global variable "dataSend"

...R