Go Down

Topic: Switching multiple Leds on/off with value from PC (Read 901 times) previous topic - next topic

JT007

Im struggling to find a code example/sketch that will drive 8 digital outputs based on a value of 0~255 transmited from a PC to the Arduino Mega.
i would be greatful if someone could write a sketch that will do this for me.  i have searched the internet for days and have asked on the projects forum already, but have not succeeded in finding a solution.  There are lots of examples for just about everything apart from this.
many thanks in anticipation
J.

CrossRoads

after defining variables, pins, Serial.begin, etc.:

Code: [Select]

if (Serial.available()>0){
LED_state = Serial.read();

LED0 = LED_state & 0x01;
if (LED0>0){
digitalWrite(LED0pin, HIGH);}
else {digitalWrite(LED0pin, LOW);}

LED1 = LED_state & 0x02;
if (LED1>0){
digitalWrite(LED1pin, HIGH);}
else {digitalWrite(LED1pin, LOW);}

// etc thru LED7 & LED7pin
}  // end if Serial.available


or use direct port manipulation and do the same.
Declare the port as outputs, write all 8 bits at once with LED_state
Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

JT007

Thanks Crossroads,
I will give it a try,
I found a similar code which is supposed to drive 4 leds but the serial input wont recognise values over 9
i found it on the web as a Ruby to Adruino code, i only wish i could remember where i found it...
if you can see anything blatantly obvious it would be appreciated

Cheers
Jason
==============================================================================================================
int ledPin = 10;
int ledPin1 = 11;
int ledPin2 = 12;
int ledPin3 = 13;
int incomingByte;// for incoming serial data


void setup() {
  pinMode(ledPin, OUTPUT);  // initialize the LED pin as an output:
  pinMode(ledPin1, OUTPUT); // initialize the LED pin as an output:
  pinMode(ledPin2, OUTPUT); // initialize the LED pin as an output:
  pinMode(ledPin3, OUTPUT); // initialize the LED pin as an output:
  Serial.begin(9600);   
  Serial.println("Ready");
}

void loop() {
// send data only when you receive data:
//if (Serial.available() > 0) {
    //incomingByte = Serial.read();
           
// only if there are bytes in the serial buffer execute the following code
  if(Serial.available()) {
    //inform that Arduino heard you saying something
    Serial.print("Arduino heard you say: ");
   
    //keep reading and printing from serial untill there are bytes in the serial buffer
     while (Serial.available()>0){
        incomingByte = Serial.read(); //read Serial
        Serial.print(incomingByte, BYTE); //prints the character just read
     }

int value = (incomingByte) % 16;
  //Serial.println(value);
   digitalWrite(ledPin, (value >> 0 ) % 2);
   digitalWrite(ledPin1, (value >> 1) % 2);
   digitalWrite(ledPin2, (value >> 2) % 2);
   digitalWrite(ledPin3, (value >> 3) % 2); // MSB
}
}
=============================================================================================

CrossRoads

int value = (incomingByte) % 16;

I believe this line masks the incoming character 4 bits (decimal 16 = HEX F or 1111).

Try getting rid of it, and then adding 4 more lines of this
  digitalWrite(ledPin3, (value >> 3) % 2); // MSB
replacing 3 with 4,5,6,7
and ledPin4,5,6,7, etc,.
Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

CrossRoads

Also, the data coming is likely characters. See asciitable.com.
So '0' will be 0x30 (00110000)
keep that in mind as you send bytes over from the IDE serial monitor display.
Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

JT007

Hi Crossroads,
im just not getting it.
I have added the full 8 bit functions
and removed the mask %16
I have figured out that %2 represents Binary

OK my understanding of whats happening (being a VB programmer) with digitalWrite(ledPin3, (value >> 3) % 2);
if value is >4 then ledpin3 is written with the binary (%2 being either 1=higher 0=not higher).
I understand what you are saying about the input serial format being Ascii characters, unfortunately im at a loss as to how i can manitulate the data value to the correct format.  i have tried a few things like changing the variable format to Char and DEC etc, but not quite getting there.
i amd still suprised that an example of transmiting a grouped digital commandhas not made it onto the site yet, or the internet for that matter (ive looked long and hard, my eyes were all bloodshot last night and i just didnt need to dress up for halloween.

The code below works great up to 9 for some reason? - it is the 0 that appears to reset all o/p to zero but then again 16 dosnt display all outputs either.
* just tested again and the 1 of the 10 char is definitely where its falling over, is it because its a/the line feed chatacter?
but then why does it not effect the println echo.

Again you advice would be most valuable
thanks Jason

//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

int ledPin = 6;
int ledPin1 = 7;
int ledPin2 = 8;
int ledPin3 = 9;
int ledPin4 = 10;
int ledPin5 = 11;
int ledPin6 = 12;
int ledPin7 = 13;


int incomingByte; // for incoming serial data


void setup() {
  pinMode(ledPin, OUTPUT);  // initialize the LED pin as an output:
  pinMode(ledPin1, OUTPUT); // initialize the LED pin as an output:
  pinMode(ledPin2, OUTPUT); // initialize the LED pin as an output:
  pinMode(ledPin3, OUTPUT); // initialize the LED pin as an output:
  pinMode(ledPin4, OUTPUT); // initialize the LED pin as an output:
  pinMode(ledPin5, OUTPUT); // initialize the LED pin as an output:
  pinMode(ledPin6, OUTPUT); // initialize the LED pin as an output:
  pinMode(ledPin7, OUTPUT); // initialize the LED pin as an output:
 
  Serial.begin(9600);   
  Serial.println("Ready");
}

void loop() {
// send data only when you receive data:
//if (Serial.available() > 0) {
    //incomingByte = Serial.read();
           
// only if there are bytes in the serial buffer execute the following code
  if(Serial.available()) {
    //inform that Arduino heard you saying something
    Serial.print("Arduino heard: ");
   
    //keep reading and printing from serial untill there are bytes in the serial buffer
     while (Serial.available()>0){
     incomingByte = Serial.read(); //read Serial
       Serial.print(incomingByte, BYTE); //prints the character just read
     }
     
    Serial.println();
   //Im seeing the value I send here,
  }
  //===================================================
  // the conversion below appears to be where its getting lost

int value = (incomingByte);// % 16; -works without this mask
  //Serial.println(value);
   digitalWrite(ledPin, (value >> 0 ) % 2);// LSB
   digitalWrite(ledPin1, (value >> 1) % 2);
   digitalWrite(ledPin2, (value >> 2) % 2);
   digitalWrite(ledPin3, (value >> 3) % 2);
   
   //digitalWrite(ledPin4, (value >> 4) % 2);
   //digitalWrite(ledPin5, (value >> 5) % 2);
   //digitalWrite(ledPin6, (value >> 6) % 2);
   //digitalWrite(ledPin7, (value >> 7) % 2); // MSB

}
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

CrossRoads

Okay, lets try it a simpler way:

after the Serial.read():
Code: [Select]

bit7 = incomingByte & B10000000;
if (bit7==0){
digitalWrite(LED7,LOW);}
else {digitalWrite (LED7, HIGH);}

bit6 = incomingByte & B010000000;
if (bit6==0){
digitalWrite(LED6,LOW);}
else {digitalWrite (LED6, HIGH);}

bit5 = incomingByte & B00100000;
if (bit5==0){
digitalWrite(LED5,LOW);}
else {digitalWrite (LED5, HIGH);}

bit4 = incomingByte & B00010000;
if (bit4==0){
digitalWrite(LED4,LOW);}
else {digitalWrite (LED4, HIGH);}

bit3 = incomingByte & B00001000;
if (bit3==0){
digitalWrite(LED3,LOW);}
else {digitalWrite (LED3, HIGH);}

bit2 = incomingByte & B00000100;
if (bit2==0){
digitalWrite(LED2,LOW);}
else {digitalWrite (LED2, HIGH);}

bit1 = incomingByte & B00000010;
if (bit1==0){
digitalWrite(LED1,LOW);}
else {digitalWrite (LED1, HIGH);}

bit0 = incomingByte & B00000001;
if (bit0==0){
digitalWrite(LED0,LOW);}
else {digitalWrite (LED0, HIGH);}

} // end if serial available
Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

JT007

Hi CrossRoads,
The penny has dropped, i get what you were trying to tell me a couple of posts ago.
when i first saw it i thought is was back to bit banging, ie i pressed 1 and relay one operated, ie sending 1-8 to drive relay 1-8 (8 seperate commands).
Its quite obvious why you are a genius.
many thanks for your help i will give it another try.
Jason.

CrossRoads

Saw this while poking around after your earlier PM - can't believe I wrote this last night & by this morning I had forgotten about it already!
In my defense, I was doing a lot of designing last night too, still had that on the brain earlier.

You have something working now?
Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

Go Up