Serial to control multiple outputs?

Hi, I have an Arduino hooked up to a few various things through some transistors.

What I need to do, is have some code where I can send something thru serial, to control a specific output.

For example, if I type: u,243 it turns on the PWM pin defined as u, at value 243?

or: b, ON

turns output defined as b, on.

Does anyone have any example code I could try? Or even just some pointers on how to do it?

-Dan :slight_smile:

Yep, you need to define your own tiny scripting language. Come up with the commands you want to recognize and start looking for the patterns once they arrive on the serial port. If the data received doesn't match any commands dispose data and start again.

You're familiar with the Arduino serial object?

Some pseudo-code...

char input[20];
byte i = 0;

loop() {

if serial.available() {
while (serial.available()) {
input = serial.read();

  • i++;*
  • if (i > 20) exit; // this isn't the right syntax but I can't remember what is right now*
  • if (check_for_command()) exit; // see above*
  • }*
  • }*
    }
    check_for_command() {
  • // compare input w 1st command, do something*
  • // compare input w 2nd command, do something*
  • // etc.*
  • input[0] = end_of_command_char; // use zero?*
    }

Thanks for that :slight_smile:

I have figured out that I have to somehow use strtok to separate the serial data, and store it to individual variables. Being a n00b to scripting, I have no idea how to do this.

All I need, is it to store the character before the , to 1 variable, then store the value after the , to another variable.

If anyone can help me out with that, I would be grateful :slight_smile:

I can recommend this

http://www.arduino.cc/playground/Code/SimpleMessageSystem

or I wrote a more complicated library for serial communication you can find here:

http://code.google.com/p/mojoduino/source/browse/#svn/trunk

Here is an example of my library

#include "mojo.h"

// Callback function for cmd "HELLO"
void Hello( Command &cmd ) {
  char param[10];
  param = cmd.getParam();  // Gets the parameter if it exists!
  Serial.println("Hello, World!");
  cmd.setReply("WORLD!");  // Set the reply!
}

void setup()
  mojo.setSerial(Serial, 'a');
  addCallback("HELLO", Hello);  // Associate function Hello with command "HELLO"
  setupDefaultCallbacks();  // Default callbacks like "ID", and "SETBAUD"
}

void loop() {
  mojo.run();
}

It uses callbacks,
to communicate you would send >>a,b:HELLO$
and it would run the code in the void Hello(Command &cmd) function and reply with

b,a:*HELLO=WORLD!$

add more commands by adding more callbacks and more functions.

commands could have params like

a,b:HELLO=TEST$

and you could access the parameter in the code using

cmd.getParam(); // would be equal to "TEST"

you could also try this!

http://arduino.cc/en/Reference/Firmata

Good luck!

Would anyone be able to help me out with the code to do this? I have been reading for the last 2 days and still stuck on how to do this :frowning:

It would be much better if you showed us what you have tried, and explained what is, and is not, working.

You've received several suggestions. Have you tried any of them?

What devices are you trying to control, and what data are you (planning to) send(ing) to the Arduino?

I am controlling blower fans, relays etc, through some NPN transistors.

Say I have a fan on the left, and I wanted to turn it on at 500 (analogWrite value). I would type: l, 500

l would be defined as a certain pin in the script, and 500 is the analog value.

What I was thinking, is have a switch, which corresponded to the letter. Then once it had found which pin I wanted, it wrote the analog value using analogWrite, and loop that until I tell it differently.

Also, it would be good if I could have it maintain that value, even if I set other fans at different values.

So if I did: r, 500

the left fan would stay at the same value as I told it previously, and the r fan would also come on at 500 etc.

This is really very simple, if the commands are always in the form "c, nnn", where c is a lower case letter and n is a digit.

void loop()
{
   char c, t;
   int nnn;

   if(Serial.available() > 0) // If there is data to read
   {
       c = Serial.read(); // Get a character
//     Serial.print("c: ");
//     Serial.println(c);
                
       delay(50);
       
       if(c >= 'a' && c <= 'z') // If it's a command
       {
          nnn = 0;
          while(Serial.available() > 0) // While there is still data
          {
             t = Serial.read(); // Read next character
//           Serial.print("t: ");
//           Serial.println(t);
             
             if(t == ',' || t == ' ')
               continue; // Skip commas and spaces
             if(t >= '0' && t <= '9') // If it's a number
             {
                nnn *= 10; // Multiply previous value by 10 
                nnn += t - '0'; // Add the new digit
             }
             else
                break;
                
             delay(50);
          }
       }

       Serial.print("Cmd: ");
       Serial.println(c);
   
       Serial.print("Val: ");
       Serial.println(nnn);
   }
   
   // Now, do something with c and nnn
   switch(c)
   {
      case 'l':
        // Turn left fan on (500 is not a valid value, by the way)
        break;
      case 'r':
        // Turn right fan on, or off
        break;
      // Add other letters here, with break after each one
   }
}

I tried this on my Arduino, with the serial monitor, and it works with simple commands like "r, 123" and "t, 1".

With the delay statements, data was grabbed by the Arduino faster than my computer could send it. I'm not sure that I understand why.

You could do nothing unless Serial.available() returned a value larger than 1, if you make sure that all values are 3 digit numbers, for instance.

Oh, that script works perfectly, thanks a lot :slight_smile:

In the switch, I just put analogWrite(3, nnn); and it works perfectly :slight_smile:

-Dan

It will work as long as the value for nnn is less than 256.

Hey guys, ive been reading this post, and id like to ask you a couple of things,

also being interested in Serial communication, and not being very expert on programming, id like to ask you to explain a couple of things,

for starters, what is the int 't' used for? to define the comma?

also, how does the arduino receive serial commands? one per loop? or can it only READ one command per loop?

another thing i didnt understand:

 if(t >= '0' && t <= '9') // If it's a number
             {
                nnn *= 10; // Multiply previous value by 10
                nnn += t - '0'; // Add the new digit
             }

thank you for any help, and sorry for the bother, im just trying to learn the best way possible. (:

for starters, what is the int 't' used for? to define the comma?

             t = Serial.read(); // Read next character

t isn't an int. It is a char. It is the character read from the serial port, and, in this case, is supposed to contain the ASCII representation of a digit (0 through 9).

also, how does the arduino receive serial commands? one per loop? or can it only READ one command per loop?

Slowly. An interrupt fires every time there is serial data to be read. The appropriate interrupt handler is called, and collects a bunch of bits from the RX pin. The 8 bits are placed in a byte, and stored in the serial input buffer, where Serial.read() can read them. The Arduino can read any number of bytes from the serial buffer on any one pass through loop. On most passes, though, there is nothing to read.

another thing i didnt understand:

If the serial data coming in contains '1','3', '8', this code will set nnn to 1 ('1' - '0' = 1), then 10 + 3 ('3' - '0' = 3) which equals 13, then to 130 + 8 ('8' - '0' = 8) which equals 138.