Wait for input...

I need some code and I am a bit confused as how to do it - I don't know that much code at the moment...

I need it to:

Wait (an infinitely long amount of time) for one piece of data from an input,
save data as 'x'
then wait for the second piece of data
save as 'y'
then wait for third piece of data
save as 'z'

flash LED

then

Wait for another piece of data from an input,
save data as 'a'
then wait for the second piece of data
save as 'b'
then wait for third piece of data
save as 'c'

then analog write data xyz as a 3 digit number to pwm pin1 and analog write data abc as a 3 digit number to pwm pin1

Hope this makes sense to someone...
All inputs are single digit and I presume that the easiest way to do it is to multiply x by 100 y by 10 and then add xyz before sending to pwm pin1.

I'm trying not to give away what the project is yet :smiley:

Thanks in advance,

Mowcius

Something like :-
while(digitalRead(pin) != LOW) { } // do nothing

// now the pin is HIGH

When you say data from an input are you talking about serial data, the above applies only to pins.
For serial:-
while(serialAvailable() == 0) { }
data = serialRead();

I had looked into the while command but was still not sure how to implement it...

And unfortunately i'm still not...

Could you write the first few lines of what I would need? Then I might grasp it...

The input is not going to be a digital read of low or high... It is a read of a number from 1 to 9.

Thanks,

Mowcius

Mike already has done:

while(serialAvailable() == 0) { }  //-snip-

x = serialRead();

Will not compile, but:

while(Serial.available() == 0) { }  // There really is nothing between the {} braces
char x = Serial.read();

Will compile.
:slight_smile:

Ok so I am making an RGB colour mixer by typing RGB values into a keyboard it will show the colour (in theory)

This code doesn't want to quite work and I'm not sure why, currently it is sending the RGB values via serial to the pc (or should be) but it doesn't want to work properly

I'm probably doing something stupid, anyway here is my messy code:

#include "binary.h"
typedef uint8_t boolean;
typedef uint8_t byte;
#include <PS2Keyboard.h>

#define DATA_PIN 4
PS2Keyboard keyboard;
int LEDR = 9;
int LEDG = 10;
int LEDB = 11;
int r1 = 0;
int r2 = 0;
int r3 = 0;
int g1 = 0;
int g2 = 0;
int g3 = 0;
int b1 = 0;
int b2 = 0;
int b3 = 0;

void setup() {
  pinMode(LEDR, OUTPUT);
  pinMode(LEDG, OUTPUT);
  pinMode(LEDB, OUTPUT);

  keyboard.begin(DATA_PIN);

  Serial.begin(9600);
  Serial.println("RGB colour Mixer");
  delay(500);
}

void loop() {
  if(keyboard.available()) {
    byte dat = keyboard.read();
    byte val = dat - '0';
    
    digitalWrite(LEDR, HIGH);
    delay(10);
    digitalWrite(LEDR, LOW);
    delay(10);
    digitalWrite(LEDR, HIGH);
    delay(10);
    digitalWrite(LEDR, LOW); 
    
    Serial.print("Type R value 0-255");

    while(digitalRead(DATA_PIN) != LOW) {}
    if(val >= 0 && val <= 9) {
    r1 = val, DEC;
    }
    
    while(digitalRead(DATA_PIN) != LOW) {}
    if(val >= 0 && val <= 9) {
    r2 = val, DEC;
    }
    
    while(digitalRead(DATA_PIN) != LOW) {}
    if(val >= 0 && val <= 9) {
    r3 = val, DEC;
    }
    
    digitalWrite(LEDG, HIGH);
    delay(10);
    digitalWrite(LEDG, LOW);
    delay(10);
    digitalWrite(LEDG, HIGH);
    delay(10);
    digitalWrite(LEDG, LOW);
  
    Serial.print("Type G value 0-255");  
  
    while(digitalRead(DATA_PIN) != LOW) {}
    if(val >= 0 && val <= 9) {
    g1 = val, DEC;
    }
    
    while(digitalRead(DATA_PIN) != LOW) {}
    if(val >= 0 && val <= 9) {
    g2 = val, DEC;
    }
    
    while(digitalRead(DATA_PIN) != LOW) {}
    if(val >= 0 && val <= 9) {
    g3 = val, DEC; 
    }
   
    digitalWrite(LEDB, HIGH);
    delay(10);
    digitalWrite(LEDB, LOW);
    delay(10);
    digitalWrite(LEDB, HIGH);
    delay(10);
    digitalWrite(LEDB, LOW); 
   
    Serial.print("Type B value 0-255"); 
  
    while(digitalRead(DATA_PIN) != LOW) {}
    if(val >= 0 && val <= 9) {
    b1 = val, DEC;
    }
    
    while(digitalRead(DATA_PIN) != LOW) {}
    if(val >= 0 && val <= 9) {
    b2 = val, DEC;
    }
    
    while(digitalRead(DATA_PIN) != LOW) {}
    if(val >= 0 && val <= 9) {
    b3 = val, DEC; 
    } 
    
    delay(500);
    Serial.print(r1);
    Serial.print(r2);
    Serial.println(r3);
    Serial.print(g1);
    Serial.print(g2);
    Serial.println(g3);
    Serial.print(b1);
    Serial.print(b2);
    Serial.println(b3);
    
  }
}

Thanks in advance,

Mowcius

This code doesn't want to quite work

Have you tried persuasion?
Chocolates and flowers?
Pension plan?

I don't quite understand - the first character you read with a keyboard.read and convert it to decimal digit, but after that, you just wait on a data pin.

This:

r1 = val, DEC;

doesn't do what you want it to. It just assigns the value of DEC to r1.

Ok, yes, even with my minimal knowledge I should probably have spotted that... I am just trying to store each value to then recall them at the end as 3 3 digit numbers. What should I be doing?

And yes, the call on the data pin was an accident, I had been trying something and obviously posted up the wrong version of the code.

Mowcius

You are so far off what you want to do it is untrue. Try this, it compiles but I have not run it. Also I am not sure what the PS2Keyboard returns as I never use this but assuming it is the simple byte from the keyboard then try this:-

#include "binary.h"
typedef uint8_t boolean;
typedef uint8_t byte;
#include <PS2Keyboard.h>

#define DATA_PIN 4
PS2Keyboard keyboard;
int LEDR = 9;
int LEDG = 10;
int LEDB = 11;
int r1 = 0;
int g1 = 0;
int b1 = 0;

void setup() {
  pinMode(LEDR, OUTPUT);
  pinMode(LEDG, OUTPUT);
  pinMode(LEDB, OUTPUT);

  keyboard.begin(DATA_PIN);

  Serial.begin(9600);
  Serial.println("RGB colour Mixer");
  delay(500);
}

int keyIn(){
  int val = 0;
  byte dat = 0;
  while(dat != 0x0d){   // keep doing this till you get a carrage return
    while(!keyboard.available()) { 
    }  // hold until there is something to read
    dat = keyboard.read();
    val = (val * 10) + (int)(dat - '0');
  }  // end of entry
  digitalWrite(LEDR, HIGH);   // flash LED to show you have recieved something
  delay(10);
  digitalWrite(LEDR, LOW);
  delay(10);
  digitalWrite(LEDR, HIGH);
  delay(10);
  digitalWrite(LEDR, LOW);
  return val;

}

void loop() {

  Serial.print("Type R value 0-255"); 
  r1 = keyIn();
  Serial.print("Type G value 0-255"); 
  g1 = keyIn();
  Serial.print("Type B value 0-255"); 
  b1 = keyIn();

  delay(500);
  Serial.print(r1);
  Serial.print(g1);
  Serial.print(b1);
}

If PS2Keyboard does not behave like this just use the normal serial input commands.

I wouldn't say that it is untrue cos I've managed... I have literally no coding experience in C++ so I am currently on a learning curve (hopefully)... I will have a fiddle with your code and see if I can get it to work...
The thing is that I know what I want to do but I have no idea of how to do it...

Mowcius

The thing is that I know what I want to do but I have no idea of how to do it...

The only thing you need to remember at this level is that a computer is the dumbest thing ever, but Boy! does it do dumb things quickly.
:wink:

Yes and I manage to give it a lot of dumb things to do when I completely mess up my code... :smiley:

Ok, I have sorted out the code now...

I sorted it out after reading the reference files in more detail (eventually)...

/* RGB Keyboard no serial v3

 *

 * Board may need resetting after turning on, not sure why but all 3 LEDs occasionally light up full when a key is pressed after turn on.

 *

 * Robin Whitfield

 * 25th June 2009

 *

 * Approx 2150 bytes

 */

 

#include "binary.h"

typedef uint8_t boolean;

typedef uint8_t byte;

#include <PS2Keyboard.h>



#define DATA_PIN 4 // Define keyboard data pin

PS2Keyboard keyboard;

int LEDR = 11; // Assign Red LED pin

int LEDG = 10; // Assign Green LED pin

int LEDB = 9; // Assign Blue LED pin

int r = 0; // Zero Red value

int g = 0; // Zero Green value

int b = 0; // Zero Blue value



void setup() {

  pinMode(LEDR, OUTPUT);  // Set Red LED pin as output

  pinMode(LEDG, OUTPUT);  // Set Green LED pin as output

  pinMode(LEDB, OUTPUT);  // Set Blue LED pin as output

  

  keyboard.begin(DATA_PIN); // Set up keyboard

}



int keyIn(){

  int key1 = 0; // Zero value for key1

  int key2 = 0; // Zero value for key2

  int key3 = 0; // Zero value for key3

  

  while(!keyboard.available()) {} // When keyboard is available:

  key1 = keyboard.read() -'0'; // Read data and assign to key1

  while(!keyboard.available()) {} // When keyboard is available

  key2 = keyboard.read() -'0'; // Read data and assign to key2

  while(!keyboard.available()) {} // When keyboard is available

  key3 = keyboard.read() -'0'; // Read data and assign to key3

  

  return ((key1*100)+(key2*10)+key3); // Turn key1, key2 and key3 into intended 3 digit number

  

}



void loop() {



  r = keyIn(); // run 'keyIn' to get Red value

  g = keyIn(); // run 'keyIn' to get Green value

  b = keyIn(); // run 'keyIn' to get Blue value

 

  r=min(r, 255); // Assign value to 255 if greater

  g=min(g, 255); // Assign value to 255 if greater

  b=min(b, 255); // Assign value to 255 if greater

  

  analogWrite(LEDR, r); // Write value to Red LED

  analogWrite(LEDG, g); // Write value to Blue LED

  analogWrite(LEDB, b); // Write value to Green LED

}

Mowcius

Here is my rendition of your idea. I've not tested it but it does compile. I'm going to dig around and see if I can find an old ps2 keyboard and try it out wit my RGB led.

In this code you do your normal setups and the rest is in the loop.
The main loop accepts keyboard inputs and only handles 0-9, esc, and enter.

When you put in the values for RGB enter them in that order (R, G, B) ie... 2,5,5,2,5,5,2,5,5. As you enter the values they will display on the serial monitor starting with red then green and finally blue (RED:255 GREEN:255 BLUE:255). The way the logic is you have to put in 3 numbers for each color ie... 10 would be entered as 010 and 1 would be 001 and 0 would be 000.

If you make a mistake at any time simply hit escape and start over. if you hit enter before all the numbers for RGB are entered it will display a message accordingly. The serial monitor window will tell you what number you hit each time and what color it was assigned to.

Once all the numbers for the RGB values are entered hit enter and the LED should change to that color.

Code...

#include <PS2Keyboard.h>

#define DATA_PIN 4
PS2Keyboard keyboard;

int ledpinR = 9;
int ledpinG = 11;
int ledpinB = 10;
int RED[3] = {0, 0, 0};
int GREEN[3] = {0, 0, 0};
int BLUE[3] = {0, 0, 0};
int keysIn = 0;

void setup() {
  keyboard.begin(DATA_PIN);
  Serial.begin(9600); 
  Serial.println("Enter RGB values. ie... 255 255 255 <enter>");
  delay(1000);
}

void loop() {
  if(keyboard.available()) {
    byte dat = keyboard.read();
    byte val = dat - '0';

    if(val >= 0 && val <= 9) {
      captureKeyboardInput((int)val);
    } else if(dat == PS2_KC_ENTER) {
      writeToRgbLed();
    } else if(dat == PS2_KC_ESC) {
      reset();
    } 
  }
}

void reset(){
  for (int i = 0; i < 3; i ++) {
    RED[i] = 0;
    GREEN[i] = 0;
    BLUE[i] = 0;
  }
  keysIn = 0;
  Serial.println("Reset!");
  Serial.println();
  Serial.println();
}

void writeToRgbLed(){
    if(keysIn >= 9){
      int red = ((RED[0]*100)+(RED[1]*10)+RED[2]);
      analogWrite(ledpinR, constrain(red, 0, 255));
      int green = ((GREEN[0]*100)+(GREEN[1]*10)+GREEN[2]);
      analogWrite(ledpinG, constrain(green, 0, 255));
      int blue = ((BLUE[0]*100)+(BLUE[1]*10)+BLUE[2]);
      analogWrite(ledpinB, constrain(blue, 0, 255));
      Serial.println("Done.");
      reset();
    }
    else{
      Serial.println("Not enough numbers were entered.");
    }
}

void captureKeyboardInput(int value){
  switch (keysIn) {
    case 0:
      RED[0] = value;
      Serial.print("RED:");
      Serial.print(RED[0]);
      keysIn ++;
      break;
    case 1:
      RED[1] = value;
      Serial.print(RED[1]);
      keysIn ++;
      break;
    case 2:
      RED[2] = value;
      Serial.print(RED[2]);
      keysIn ++;
      break;
    case 3:
      GREEN[0] = value;
      Serial.print(" GREEN:");
      Serial.print(GREEN[0]);
      keysIn ++;
      break;
    case 4:
      GREEN[1] = value;
      Serial.print(GREEN[1]);
      keysIn ++;
      break;      
    case 5:
      GREEN[2] = value;
      Serial.print(GREEN[2]);
      keysIn ++;
      break;
    case 6:
      BLUE[0] = value;
      Serial.print(" BLUE:");
      Serial.print(BLUE[0]);
      keysIn ++;
      break; 
    case 7:
      BLUE[1] = value;
      Serial.print(BLUE[1]);
      keysIn ++;
      break;
    case 8:
      BLUE[2] = value;
      Serial.print(BLUE[2]);
      Serial.println();
      keysIn ++;
      break; 
  }
}

Ok, i'll try that a bit later, thanks...

It looks like a better rendition of my idea than mine...

I like the idea of ESC if you go wrong...

I also had the issue of having to put in 010 etc, is there any way that if you are pressing ENTER after each one to confirm then you can make it take it literally as typed e.g. it would take 10 as 10 not 1 and 0 and then you wouldn't have to fiddle about with multiplying numbers...

I still haven't received my sparkfun order or I would have a video/some more interesting photos for you with a BlinkM MaxM lighting up a room...

Mowcius

I also had the issue of having to put in 010 etc, is there any way that if you are pressing ENTER after each one to confirm then you can make it take it literally as typed e.g. it would take 10 as 10 not 1 and 0 and then you wouldn't have to fiddle about with multiplying numbers...

Yeah, because the enter key is a confirmation that all colors are entered you have to enter 3 digits for each color. If it were coded to accept an enter key after each color you could do exactly what you said and the code should be alot shorter too.

Or you could use "atoi ()", though you still need some editing to cope with backspace or stuff like that.