Go Down

Topic: Dimmer example not working (Read 3680 times) previous topic - next topic

Jim H

Hi Folks,

I'm trying to get the "Dimmer" example to work but for some reason it doesn't work as expected. When I send the first number the LED lights up but subsequent numbers sent make no change to the LED??
Any ideas what could be happening?

Here's the code:

int ledPin = 9;

void setup()
{
 // begin the serial communication
 Serial.begin(9600);
 pinMode(ledPin, OUTPUT);
}

void loop()
{
 byte val;
 
 // check if data has been sent from the computer
 if (Serial.available()) {
   // read the most recent byte (which will be from 0 to 255)
   val = Serial.read();
   // set the brightness of the LED
   analogWrite(ledPin, val);
 }
}


Cheers

Jim H

mikalhart

#1
Dec 08, 2008, 01:16 am Last Edit: Dec 08, 2008, 01:17 am by mikalhart Reason: 1
Jim, I'm assuming you're using the Arduino console to send digits?  Try the following modification to see if it helps:

Code: [Select]
if (Serial.available()) {
  // read the most recent byte (which will be from 0 to 255)
  val = Serial.read();
  if (val >= '0' && val <= '9') // ignore non-digits
  {
   val = 25 * (val - '0'); // scale to 0, 25, 50, 75, etc.
   // set the brightness of the LED
   analogWrite(ledPin, val);
 }
}


If that helps and you are curious why, reply back.

Mikal

Jim H

Hmmm, I'm curious. It doesn't make any sense at all to me. It works yes but I can't figure out what's going on. I tried deleting the "(val - "0")" and just replaced it with 25 * val in the mistaken idea that taking "0" away from anything would make no difference to the result. However when I did this sending 1, 2 or 3 increases the brightness but sending 4 dips back down to dim again??

What's going on?

Thanks

Jim H

Jim H

Slowly something is sinking in - it appears to be something to do with the last character sent - hence the '0' to '9'.

Quote
"Strings are represented as arrays of type char and are null-terminated."


So perhaps it's a string issue to do with Serial.read()?

I'm still pretty lost though.

Does this mean that I can't smoothly dim LEDs but have to use 25 * steps up to 215 instead?

Thanks

Jim H

mikalhart

You're on the right track, Jim.

In C, '0' and 0 are different things.  0 is 0, and '0' is another way to write the number 48, which is the ASCII encoding for the digit '0'.

When you read a digit from the serial port, you are reading ASCII-encoded values.  If you type 0 on the serial console, what comes across the wire is the number 48.  To convert it to a usable number, you have to subtract 48, hence the expression (val - '0').  The assignment

Code: [Select]
val = 25 * (val - '0')

was just an test to make sure the wiring was good.  You can now use any expression you want to generate values for val between 0 and 255.  You don't have to use 25* steps at all.  Do whatever you want.

When you removed the -'0', you were effectively saying val = 25 * 48 or 1200.  1200 is obviously not between 0 and 255; hence the unpredictable results.

Mikal


Jim H

That makes sense but unfortunately I'm still not able to get a response to anything other than the last character sent: so 222 is the same intensity as 2?

Thanks

Jim H

mikalhart

#6
Dec 08, 2008, 06:20 pm Last Edit: Dec 08, 2008, 06:24 pm by mikalhart Reason: 1
Consider what happens when you send the string "529".  A "5" arrives and your code sets the LED to medium bright.  But immediately afterward, the '2' and the '9' arrive, setting the LED to dim and then bright.  It happens so fast that all your eye detects is the bright/last one.

I you want the LED to visibly go to different values, try putting a 500ms delay in write after the analogWrite:

Code: [Select]
delay(500);

If you are trying to type three-digit values, then you need to add some parsing code.  I need to run now, but I can help with this later.  

Mikal

Jim H

Sorry Mikal,

I've been tinkering with the code in every way I can think of but I'm not getting anywhere. Yes, I'd like to be able to send numbers of more than 1 character so if parsing would help then that's what I need help to do.

What I can't understand is why it doesn't work in the first place - its an "Example" file after all!

Jim H

mikalhart

#8
Dec 08, 2008, 11:05 pm Last Edit: Dec 08, 2008, 11:08 pm by mikalhart Reason: 1
Ah, but the example is written to communicate with the Processing sketch (also provided) that is generating binary bytes, not with a human typing ASCII characters.  A computer can send any value between 0 and 255.  You can only (easily) type only a small percentage of these... characters 0-9, A-Z, etc.

What will your ultimate usage model be?  I can help you write a routine that lets a human type three-digit numbers if that's ultimately what you want.

Mikal

Jim H

I'm trying to create an interface between Runtime Revolution (a modern relative of Hypercard) and the Arduino. I'd like to be able to send 3 digit numbers so that I can fully control PWM from RunRev.

Jim H

mcgrath3

Jim, I use Revolution/LiveCode and am trying to connect the Arduino Uno which uses a different method to register the serial port as a modem and does not use the FTDIUSBSerial driver. Did you get this working in Revolution? What version of Arduino are you using?

Thanks
Tom

Jim H

Hi Tom,

Yes I got it to work pretty well. I was using the Duemillanova. I'm a bit rusty now because I haven't used it in a while but RunRev/Livecode works brilliantly with it.

Go Up