Lets say I have something that sends a command to the Arduino (for example, a PC sending through serial, Ethernet, etc). I want the Arduino to "check" what command it is and run a specific function linked to that command.
I don't need a very explanatory answer, just give me something so I can learn from. A sketch that shows a similar idea would be good, I can try to interpret it and adapt/remake for me.
The idea is to use the Arduino for a lot of different things. Let's say:
Turn a bunch of leds on/off;
Read data from a sensor and send it through Ethernet/I2C/Serial;
Control a servo.
But I want the Arduino to do that when I tell it to (in this case, sending the command through serial, etc). So let's say I send it 1, I'll want it to run the 1 function (turning the LEDs on/off).
I already took a tutorial course on Arduino programming, but I'm clueless on how to do this job.
-
You might like to use my CLI library as a starting point: github.com/MajenkoLibraries/CLIMajenko– Majenko2015年08月20日 09:11:39 +00:00Commented Aug 20, 2015 at 9:11
2 Answers 2
If you want it really barebones and easy, you can checkout the Arduino "Dimmer" example sketch.
Instead of changing the brightness of an attached pin, you could take the input you send it over the serial console and execute various functions, depending on what you receive.
Something like this:
boolean newCommand = false;
void setup()
{
// initialize the serial communication:
Serial.begin(9600);
// other setup stuff here
}
void loop()
{
byte command;
// check if data has been sent from the computer:
if (Serial.available())
{
// read the most recent byte (which will be from 0 to 255):
command = Serial.read();
// say that you received a new command
newCommand = true;
}
// is there a new command?
if (newCommand == true)
{
// do something depending on what command you received
switch(command)
{
// if you receive command "1", do something
case 1: functionWhatever();
break; // "break" out of the switch. otherwise it would continue executing the following commands as well
case 2: functionWhatever2();
break;
//for cases that are not caught, send out an error
default: Serial.write("invalid command");
break;
}
}
}
If you want to use an existing library, you might want to check out: EasyTransfer.
It can be used for communication between two Arduinos, which you then can use to execute functions on the other side of the line.
The code itself is relatively simple, so you might be able to adapt it to communicate with a processing script on your computer for example.
-
1Thank you for your answer! The sketch was very clear, and the library seems like a good idea if I'm able to edit it... I'm thinking of connecting a Raspberry Pi and a Arduino via I2C. Would editing the library allow it? I'll try to figure it out latertwski– twski2015年08月20日 19:58:24 +00:00Commented Aug 20, 2015 at 19:58
If you just want some example code, here is a smallish sketch I wrote that controls some LEDs via a shift register. Exactly how the shift register works isn't important, but you can see the basic idea for taking input from the serial port and decoding it:
#include <SPI.h>
const byte LATCH = 10;
const byte numberOfChips = 4;
const byte maxLEDs = numberOfChips * 8;
byte LEDdata [numberOfChips] = { 0 }; // initial pattern
void refreshLEDs ()
{
digitalWrite (LATCH, LOW);
for (int i = numberOfChips - 1; i >= 0; i--)
SPI.transfer (LEDdata [i]);
digitalWrite (LATCH, HIGH);
} // end of refreshLEDs
// how much serial data we expect before a newline
const unsigned int MAX_INPUT = 10;
void setup ()
{
Serial.begin(115200);
SPI.begin ();
refreshLEDs ();
} // end of setup
// here to process incoming serial data after a terminator received
void process_data (char * data)
{
Serial.print ("Got command: ");
Serial.println (data);
// C: clear all bits
switch (toupper (data [0]))
{
case 'C':
{
for (int i = 0; i < numberOfChips; i++)
LEDdata [i] = 0;
Serial.println ("All bits cleared.");
refreshLEDs ();
return;
}
// S: set all bits
case 'S':
{
for (int i = 0; i < numberOfChips; i++)
LEDdata [i] = 0xFF;
Serial.println ("All bits set.");
refreshLEDs ();
return;
}
// I: invert all bits
case 'I':
{
for (int i = 0; i < numberOfChips; i++)
LEDdata [i] ^= 0xFF;
Serial.println ("All bits inverted.");
refreshLEDs ();
return;
}
} // end of switch
// otherwise: nnx
// where nn is 1 to 89 and x is 0 for off, or 1 for on
// check we got numbers
for (int i = 0; i < 3; i++)
if (!isdigit (data [i]))
{
Serial.println ("Did not get 3 digits.");
return;
}
// convert first 2 digits to the LED number
byte led = (data [0] - '0') * 10 + (data [1] - '0');
// convert third digit to state (0 = off)
byte state = data [2] - '0'; // 0 = off, otherwise on
if (led > maxLEDs)
{
Serial.println ("LED # too high.");
return;
}
led--; // make zero relative
// divide by 8 to work out which chip
byte chip = led / 8; // which chip
// remainder is bit number
byte bit = 1 << (led % 8);
// turn bit on or off
if (state)
LEDdata [chip] |= bit;
else
LEDdata [chip] &= ~ bit;
Serial.print ("Turning ");
Serial.print (state ? "on" : "off");
Serial.print (" bit ");
Serial.print (led & 0x7, DEC);
Serial.print (" on chip ");
Serial.println (chip, DEC);
refreshLEDs ();
} // end of process_data
void loop()
{
static char input_line [MAX_INPUT];
static unsigned int input_pos = 0;
if (Serial.available () > 0)
{
char inByte = Serial.read ();
switch (inByte)
{
case '\n': // end of text
input_line [input_pos] = 0; // terminating null byte
// terminator reached! process input_line here ...
process_data (input_line);
// reset buffer for next time
input_pos = 0;
break;
case '\r': // discard carriage return
break;
default:
// keep adding if not full ... allow for terminating null byte
if (input_pos < (MAX_INPUT - 1))
input_line [input_pos++] = inByte;
break;
} // end of switch
} // end of incoming data
// do other stuff here like testing digital input (button presses) ...
} // end of loop
Example of commands understood by the above code:
C <-- clear all LEDs
S <-- set (turn on ) all LEDs
I <-- invert all LEDs (turn off if on, and vice-versa)
021 <-- turn LED 02 on
020 <-- turn LED 02 off
161 <-- turn LED 16 on
This code processes a 3-digit string as:
nnS
Where "nn" is the LED number and S is the new state (1 = on, 0 = off).
Other examples
There is a more elaborate example on my page about using a 74HC595 output shift register as a port-expander
-
Your answer actually made me research about a shift register and now I'm actually considering it for saving some output pins on my project, thanks!twski– twski2015年08月20日 20:00:33 +00:00Commented Aug 20, 2015 at 20:00