What could be the fastest working solution?

Good day!

I am currently programming a piece of software that should make five leds turn up via milisecond delay (so it appeas they are all on at the same time), and return a string that notifies when the five buttons corresponding to those leds have been pressed. Now I am using 8+13 pins to turn on and off a LED matrix of 42 keys, and 42 pins connected to 5V output as input pins telling me when the power was cut off (so the input is 0). I am doing this as an interface with the computer, and was wondering a few things:

  1. What is faster: sending a string containing ten numbers (01-42 * 5) and having a function in arduino to figure out what to do with it, or sending pin numbers (note that when a button is pressed, the incoming signal will mean set one pin to high(the ground of the led) and one to low(the source of power for the LED), and then set another pin to low(the ground for the new LED) and another to high(source for the new LED), all this for five "buttons" at a time. So is it faster to have 42 "if" statements in arduino or have a function that will read the pins directly and then turn on/off the corresponding pins?
  2. What is the max baud rate a MEGA can handle?
  3. I have done this on an example of six pins, the "if" statement version. After a keyboard keypress, it takes the arduino more then half a second to turn on the corresponding led(s). If i make a programm that sends different signals at less than 750 millis delay, none of the leds turn on. So what is the maximum processing speed of the arduino?

Please answer these questions as best as you can, because it is vital that the lights turn on as fast as possible (the reaction time is key).

Thank you in advance.

Sending strings requires converting numbers to strings on the sending end, collecting the characters into an array, parsing the array, and converting the strings back to ints on the receiving end. That is not a process that is really compatible with speed.

Sending binary data is orders of magnitude faster. Pin numbers fit into bytes until you get past 255 pins, which no Arduino does.

  1. What is the max baud rate a MEGA can handle?

I do believe you could figure this out yourself. Look at the drop down list in the Serial Monitor. The list matches the speeds that the Serial instances can operate at reliably.

  1. I have done this on an example of six pins, the "if" statement version.

It is not clear to me why you need any if statements when you know the pin numbers you are to manipulate. So, please show at least some of the code you have to explain why.

Ok, so I figured that binary data would be faster, the problem is, I have no idea how to send binary data from vb.net. As for the code, I seem to have uploaded it, but the genious that I am forgot to save the file, so it's on my arduino, and I have no idea how to retrieve it. I might google this when time lets me. I guess I could write an example, to let you see what I mean.

Say I have six leds (that's three keys, as each key has two different leds). The led set that is on (always one of two leds on a key, per say only red or only green leds). There is a green and a red led tied to one output(eg. pins 1, 2, and 3), but each has it's own ground pin (pins 4,5,6,7,8,9). So per say pin 1 is high and pin 4 is low, the first green led is on, pin1 high and pin 5 low the first red etc, pin 2 high and pin 6 low the scnd green, you get the idea. So it's green red green red green red. I think the code went something like this:

char keysOn[9]

void setup() {
Serial.begin(128000);
for (int i=1;i>8;i++){
      pinMode(i,OUTPUT);}

for (int i=4;i>8;i++){
      digitalWrite(i,HIGH);}
}
 //Now as I am writing this by hand, this is going to be a bit off
void loop(){
if Serial.avaliable(){
   //the input is always 9 characters '<' - the character that says start reading, followed by xx;yy;z;, where xx is the first of the two keys on, yy is the second, and z is red or green on that button(0 or 1).
int i=0;    
while Serial.avaliable(){
         keysOn(i)=Serial.read();
         i++;}}
//I can't remember how i got the strings into integers for the pins, but the rest went
if xx=sth{
   digitalWrite(1,HIGH);
   digitalWrite(4,LOW);
   digitalWrite(1,LOW);
   digitalWrite(4,HIGH);}
if xx=sthelse{
   digitalWrite(1,HIGH);
   digitalWrite(5,LOW);
   digitalWrite(1,LOW);
   digitalWrite(5,HIGH);}}

//etc for other xx and yy, so every pin is covered. xx and yy are 01, 02, 03... so keys that are to be on, for testing purposes only 2 at a time.

I know this code is very wrong in certain places, and takes awfully long to do anything, but it did turn the corresponding leds on or off (i set if the first in the array was '!', it shut all of them off). Since 6 leds wired does not make a matrix yet, I have no idea how to code the whole deal until i try (I am currently waiting for some breadboarding cable to arrive, can't do a thing without it).

Anyway, reviewing my code now I realise how roundabout it is, but I am interested in what you said about the bytes. Could I have an example and maybe some quick explanation by it? I'd really appreciate it.

the problem is, I have no idea how to send binary data from vb.net.

Post the code that you are using. I'm betting that you are having to perform all kinds of magic to convert the data that you have to strings and coerce VB to send that data. Sending binary data is much easier, generally. Depends on the various classes involved, etc.

I have no idea how to retrieve it.

Google away, but prepare to be disappointed. Compiling is similar to making mashed potatoes. It is a one way process. You can't get the source code back from the Arduino.

Take this as an opportunity to rewrite the code better. I'd guess that what you were doing before with all the if statements was string comparison. If the pin number was "1", do this. If it was "2", do that.

Right, exactly. If one part of the string is this, do that etc. String comparison you call it... that'll cut my explanations short :stuck_out_tongue:

Anyway, the vb.net code isn't that hard, there's a simple process that initializes the serial connection, and I sent the string using

Public s As New System.IO.Ports.SerialPort

 Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        s.Close()
        s.PortName = "COM4"  'will need to change to your port number
        s.BaudRate = 128000
        s.DataBits = 8
        s.Parity = System.IO.Ports.Parity.None
        s.StopBits = System.IO.Ports.StopBits.One
        s.Handshake = System.IO.Ports.Handshake.None
        s.Encoding = System.Text.Encoding.ASCII 'very important!
        s.Open()
        s.RtsEnable = True
    End Sub

'this is the part that initializes the serial connection on start. Next, the sending on pressing a form button:

 Private Sub Form1_KeyDown(ByVal sender As Object, ByVal e As KeyEventArgs) Handles Me.KeyDown
If e.KeyCode = Keys.F Then
            If inout = 0 Then
                inout = 1
            ElseIf inout = 1 Then
                inout = 0
            End If
        End If
        If e.KeyCode = Keys.K Then
            Label1.Text &= e.KeyCode
            s.WriteLine("<0;2;" & inout & ";")
            Label1.Text = "<0;2;" & inout & ";"
        End If
        If e.KeyCode = Keys.U Then
            Label1.Text &= e.KeyCode
            s.WriteLine("<1;2;" & inout & ";")
            Label1.Text = "<0;2;" & inout & ";"
        End If
        If e.KeyCode = Keys.I Then
            Label1.Text &= e.KeyCode
            s.WriteLine("<1;3;" & inout & ";")
            Label1.Text = "<0;2;" & inout & ";"
        End If
        If e.KeyCode = Keys.O Then
            Label1.Text &= e.KeyCode
            s.WriteLine("<2;3;" & inout & ";")
            Label1.Text = "<0;2;" & inout & ";"
        End If
        If e.KeyCode = Keys.L Then
            Label1.Text &= e.KeyCode
            s.WriteLine("<0;3;" & inout & ";")
        End If
        If e.KeyCode = Keys.J Then
            Label1.Text &= e.KeyCode
            s.WriteLine("<1;0;" & inout & ";")
        End If
    End Sub

'the inout here is the red/green switch, i let the arduino treat that with an if.

As you said, I sent a string, turned it into characters in the arduino, and then compared them to get the correct pins to turn on. I also found the file on my disc, lodged somewhere I forgot I put it xD Here's the code on the arduino:

#include <stdio.h>
#include <stdlib.h>
char LedOn[10];
char LedOff[10];
int pin[16];
int t=0;
int on=0;
int off=0;
void setup(){
  Serial.begin(128000);
  pinMode(23,OUTPUT);
  pinMode(27,OUTPUT);
  pinMode(33,OUTPUT);
  pinMode(35,OUTPUT);
  pinMode(49,OUTPUT);
  pinMode(53,OUTPUT);
  pinMode(19,OUTPUT);
  pinMode(15,OUTPUT);
  pinMode(2,OUTPUT);
  pin[0]=15;
  pin[1]=2;
  pin[2]=19;
  pin[3]=23;
  pin[4]=27;
  pin[5]=33;
  pin[6]=35;
  pin[7]=49;
  pin[8]=53;
 }
void loop(){
  if (t<2){
    test();
    delay(1000);
    t++;}
  SerialRead();
  Serial.flush();
  if (on==1){
    makeemshine();}
        }
void test(){
for (int i=3;i<9;i++){
  digitalWrite(pin[i],HIGH);}
for (int j=0;j<10000;j++){
  for (int i=0;i<3;i++){
  digitalWrite(pin[i],HIGH);
   if (i==0){
     digitalWrite(pin[3],LOW);
     digitalWrite(pin[3],HIGH);
     digitalWrite(pin[4],LOW);
     digitalWrite(pin[4],HIGH);
   }
   if (i==1){
     digitalWrite(pin[5],LOW);
     
     digitalWrite(pin[5],HIGH);
     
     digitalWrite(pin[6],LOW);
     
     digitalWrite(pin[6],HIGH);
   }
   if (i==2){
     digitalWrite(pin[7],LOW);
     
     digitalWrite(pin[7],HIGH);
     
     digitalWrite(pin[8],LOW);
     
     digitalWrite(pin[8],HIGH);
     }
}}}
void turnoff(){
  for (int i=2;i<54;i++){
    digitalWrite(i,HIGH);}}
void LEDon(int tipka,int smer){
    if (smer==0){
     if (tipka==1){
       digitalWrite(pin[0],HIGH);
       digitalWrite(pin[3],LOW);}
     if  (tipka==2){
       digitalWrite(pin[1],HIGH);
       digitalWrite(pin[5],LOW);}
     if (tipka==3){
       digitalWrite(pin[2],HIGH);
       digitalWrite(pin[7],LOW);}}
  if (smer==1){
     if (tipka==1){
       digitalWrite(pin[4],LOW);}
     if  (tipka==2){
       digitalWrite(pin[6],LOW);}
     if (tipka==3){
       digitalWrite(pin[8],LOW);}}}

void LEDoff(int tipka){
   if (tipka==1){
     digitalWrite(pin[0],HIGH);  
     digitalWrite(pin[3],HIGH);
   digitalWrite(pin[4],HIGH);}
     if  (tipka==2){
     digitalWrite(pin[1],HIGH);  
     digitalWrite(pin[5],HIGH);
   digitalWrite(pin[6],HIGH);}
     if (tipka==3){
       digitalWrite(pin[2],HIGH);
       digitalWrite(pin[7],HIGH);
     digitalWrite(pin[8],HIGH);}}
  
  
void SerialRead(){
  if (Serial.available()>0){
    char s=Serial.read();
    if (char(s)=='<'){
      on=1;
      int k=0;
        while (Serial.available()>0){
          LedOn[k]=Serial.read();
          delay(100);
          k++;          
          }Serial.flush();}
     if (char(s)=='!'){
        on=0;
        Serial.flush();
//         int k=0;
//         while (Serial.available()){
//           LedOff[k]=Serial.read();
//           k++;
           }}}
void makeemshine(){
  int tipka1=int(LedOn[0])-48;
  int tipka2=int(LedOn[2])-48;
    int vennot=int(LedOn[4])-48;
  LEDon(tipka1,vennot);
  delay(5);
  LEDoff(tipka1);
  LEDon(tipka2,vennot);
  delay(5);
  LEDoff(tipka2);}

As you can see, I let the arduino do most of the work. How do I handle byte stream with the arduino, that would save me a lot of code and processing?

  1. What is the max baud rate a MEGA can handle?

Not tested with a MEGA but I have run multiple UNO's for weeks in a test at 230400 and even 345600 (double and triple the max speed of the IDE serial monitor).
With short experiments even higher baudrates but those were definitely not standard.

To capture the data under win7/64 I used putty.exe

Rob

According to the ATMEGA 1280 datasheet, Page 231 - Table 22-12 Examples of UBRRn Settings for Commonly Used Oscillator Frequencies:
http://atmel.com/dyn/resources/prod_documents/doc2549.pdf

it looks like you can go up to as high as 2Mbps with the normal 16Mhz resonator/oscillator and the U2Xn: Double the USART Transmission Speed bit set. I also believe I read the max for the FTDI chip is 3Mbps - so theoretically 2Mbps is possible, but in practice I'm thinking unless the cable is super short there will probably be too much noise for reliable communication at the top end.

Here is a thread in the old forums with more info:
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1235580746

I would suggest keep turning it up until it starts showing errors.

willnue

Instead of doing serial if's like this
if (smer==1){
if (tipka==1){
digitalWrite(pin[4],LOW);}
if (tipka==2){
digitalWrite(pin[6],LOW);}
if (tipka==3){
digitalWrite(pin[8],LOW);}}}

why not rewrite it as
switch (tipka){
case 1:
digitalWrite (whatever, LOW);
break;
}

Then you only execute one of the if's.
Where you have a bunch of those, and in some cases if's nested within if's it looks like, I bet the actual running would cut out a bunch of comparisons.

I agree with CrossRoads on the use of a SWITCH/CASE statement being much faster than the multiple IF/THEN statements.

If you really need to go faster you can look into Port Registers, which will allow you to update mulitple pins at once etc...

Port Registers (UNO):

See this thread for MEGA detail:
Pinout for Port Registers on Arduino Mega?? :
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1245229578

willnue