• Welcome to Overclockers Forums! Join us to reply in threads, receive reduced ads, and to customize your site experience!

C and Arduino help

Overclockers is supported by our readers. When you click a link to make a purchase, we may earn a commission. Learn More.

carlw

Registered
Joined
Aug 9, 2011
Hi guys, I'm new here.
I'm doing C/Arduino at university and I'm having some trouble already (programming is not exactly my forte) so I thought I'd post here as it's generally easier than asking my tutor. (I've already asked him quite a lot and he doesn't explain it very well).

Here is my simple program for switching on an LED. If we change the variable "pulserate" to 0 it shouldn't switch on at all. If we change it to 10 it should stay on all the time and anything inbetween has to make it flash on and off.

I think I'm pretty close to getting this one correct, but 0 and 10 don't work properly.

//Workshop 1 Task 2
int LEDPin = 0;

int pulserate = 0; //0-10 where 0 is off and 10 is on

void setup() {
//initialise the digital pin as an output
pinMode(LEDPin, OUTPUT);
}


void loop() {
if (pulserate == 10) {
digitalWrite(LEDPin, HIGH);
}
else (delay(pulserate*100));
digitalWrite(LEDPin, LOW);
delay(pulserate*100);
digitalWrite(LEDPin, HIGH);
}
 
Very simple syntax error, below is the fixed code with the stuff I changed in bold.

Code:
//Workshop 1 Task 2
int LEDPin = 0;

int pulserate = 0; //0-10 where 0 is off and 10 is on

void setup() {
//initialise the digital pin as an output
pinMode(LEDPin, OUTPUT);
}


void loop() {
  if (pulserate == 10) {
    digitalWrite(LEDPin, HIGH);
  }
  else [B]{[/B]
    delay(pulserate*100);
    digitalWrite(LEDPin, LOW);
    delay(pulserate*100);
    digitalWrite(LEDPin, HIGH);
  [B]}[/B]
}



You'll need to add an "else if" statement between the if and the else statements you already have to cover zero.
As it stands zero will go into the else category and turn the LED on and off every 0ms. The end result is essentially a ~1mhz PWM at 50%.


EDIT:
A couple thoughts:

Pin 0 (and pin 1) is used for serial communication on Arduinos, sometimes it gives very odd results if you use it for other things, pins 2 through 18 are a better bet. (pins 14 through 18 are the analog input pins 0-5, they'll also do digital output).
The second word of variables is usually capitalized, thusly "pulseRate", it makes it a bit easier to read is all. Arduinos are case sensitive, so "pulserate" and "pulseRate" are different variables! This can confuse the hell out of a person!
 
So everything in the else statement needed to be inside { and } ???
That was a simple fix. Thank you very much.

Great, I'll change those variables to include those caps.
What is the diff between digital and analog in the Arduino sense?
 
Yup, you had ( ) around the else statement's body rather than { }, simple as that! I've done similar things, it's a pretty common mistake. I tend to forget the closing } a lot.

Analog means different things depending on whether it's input (analogRead) or output (analogWrite).

A statement such as "x = analogRead(3)" takes a voltage reading of analog input pin 3, the range goes from 0 (0v) to 1023 (5v, or whatever is being fed to the Arduino as VCC, if it's running at 3.3v 1023 is 3.3v).
If nothing is connected to the pin, or if whatever is connected is not actively sourcing (putting out) or sinking (taking in) voltage, you will be reading a "floating" pin, and the value could be anywhere between 0 and 1023. This can be interesting to play with, though in practice it's usually between 330 and 380. If you touch the pin the value will be different.

Now analogWrite is a completely different beast, really it shouldn't be called analog, not sure why the Arduino folks decided to call it that.
It is a PulseWidthModulation output (PWM for short). Only certain pins have PWM output capability, on the official Arduino boards they're marked with a - I believe. 3,5,6,10,11 are the pins that can do it.
As far as what exactly PWM is, I'll put down the brief version, for more detail hit up wikipedia.

PWM essentially is exceedingly fast digital writes.
In arduinoland a PWM value of 0 is the same as digitalWrite(pin, LOW), while a PWM value of 255 is the same as writing the pin HIGH.
It's 1 to 254 that are interesting.
A PWM value of 100 turns the pin HIGH for 100 ticks, and then LOW for 156 ticks.
A PWM value of 50 turns the pin HIGH for 50 ticks and then LOW for 205 ticks.
A PWM value of 200 turns the pin HIGH for 200 ticks and then LOW for 55 ticks.
A "tick" is either one 500th of a second or one 1000th of a second, depending on which pin you use.
Depending on the chip and how you set things, PWM rates over 1mhz are possible (that meaning a tick is one 1,000,000th of a second!).

The end result is that an LED connected to a PWM pin will display a variable brightness, mostly because the human eye can't see the blinking on and off, instead it averages it out.

Here's a quick sketch to display the effect, connect an LED to pin 3 with a resistor to ground (always always always use a resistor with LEDs, your instructor should be slamming that into your head constantly, cause it's important (if he isn't, tell him Bobnova says he should be :p). Failure to do so will kill the LED and the Arduino brains eventually), then upload this:
Code:
byte pwmPin = 11;

void setup(){
  pinMode (pwmPin, OUTPUT); 
}

void loop(){
  for (int x = 0 ; x < 256 ; x++){
    analogWrite(pwmPin, x);
    delay(20);
  }
  for (int x = 255 ; x > 0 ; x--){
    analogWrite(pwmPin, x);
    delay(20);
  }
}

I need to restrain myself, I'll babble about this for quite a while and you'll end up with a wall of text only vaguely related to your question :D
(Evidence is above, we're already into "for" loops. "for" loops are wonderful fun! I expect they'll be next after if/else statements. Sidenote on those: You can have a ton of "if else" checks between the first "if" and the eventual "else". You can also leave the "else" off entirely, and if none of the "if" or "else if" statements returns true nothing will happen)
See? I'm doing it again.
 
Last edited:
I appreciate the explanation....I think I kinda get it.
But honestly, the main point I take away from all this is to use pins 2-13 just to be safe :D

And yes, we've been drilled about using resistors. No one has blown an LED yet.

I'm just installing this "Fritzing" diagram sketching program. I may have a question soon about how to connect up more LEDs. It says to be careful about using resistors for each LED. That seems strange to me, when the current passes through the first resistor isn't this issue already dealt with or does it become an unsafe current again after going through the first LED?
 
That was the most important part (beyond using a resistor), so you're on the right track!

To understand exactly why you need one resistor per LED I'll have to delve into some background, it's relatively simple though.

To start off with, an LED has a voltage below which it will simply not turn on (or will only just basely sort of turn on). This is the "forward voltage". What that means we can leave for later, suffice to say that an LED with a forward voltage of 2.2 volts requires 2.2 volts to turn on.

Here's the issue: Once above it's minimum forward voltage, an LED has essentially zero resistance, that means that a LOT of current flows through it, quickly overheating the LED (and/or the microcontroller sourcing the current!) and frying it.
LED's have a second important number, their current rating. A typical red LED has a forward voltage of 1.8v and a current rating of 10-20 milliamps (ma).
If you tell the Arduino to turn a pin HIGH it puts out five volts (definitely over 1.8v!) and far more than 10-20ma of current, exactly how much I don't know, but a lot more than that.
Hence we need a resistor to provide some resistance and prevent excessive current flow (that's what resistors "resist", current flow).
That's the simple part, now for slightly more complexity :D

Once above the forward voltage of a LED the current flow is responsible for the brightness of the LED. More current = brighter LED. Less current = dimmer LED.

Ok, now we finally get to the answer to the question of why you need one resistor per LED!
Say you have two identical LEDs, they both want 1.8v and they both want 10ma of current.
You connect the positive leads of the LEDs to a pair of Arduino output pins, you then connect the negative leads to ground via a single resistor sized for 10ma of current.

Turn one LED on, and it's nice and bright!
Turn both LEDs on and they both turn on, but they are dim.
Why? Because they have to share the 10ma of current! The result is that each LED only gets 5ma, and hence is dim.

Ok that didn't work, lets size the resistor for 20ma so the LEDs are bright when both are turned on!
Downside: If you only turn one LED on it gets 20ma, rather more than the 10ma it is rated for and it goes POP! RIP LED.


You can safely do the first if you don't mind dim LEDs, it won't hurt anything.
Alternatively you can connect the positive lead of the first LED to the Arduino, the negative lead to the next LED's positive lead, that LED's negative to the next positive, and so on. Add the forward voltages together to get the total voltage you need, and size the resistor for whatever an individual LED wants.
The downside is that you can only turn on all the LEDs or none of the LEDs with this wiring scheme.

There are other schemes known as "multiplexing" which I expect you'll get to eventually in your class, they're a bit of a headache.


EDIT:
If you want to be that annoying guy that does more than the instructor asks for, the stuff in the spoiler box might be fun.
Code:
//Workshop 1 Task 2
int LEDPin = 0;

int pulseRate = 0; //0-10 where 0 is off and 10 is on

void setup() {
//initialise the digital pin as an output
pinMode(LEDPin, OUTPUT);
}


void loop() {
  if (pulseRate == 10) {
    digitalWrite(LEDPin, HIGH);
    delay(2000);
  }
  else if (pulseRate == 0){
    digitalWrite(LEDPin, LOW);
    delay(2000);
  }
  else {
    delay(pulseRate*100);
    digitalWrite(LEDPin, LOW);
    delay(pulseRate*100);
    digitalWrite(LEDPin, HIGH);
  }
  pulseRate++;
  if (pulseRate == 11){
    pulseRate = 0;
  }
}

Pretty simple change, see if you can figure out what it does, then stuff it into the arduino and see if you're right :D
 
Last edited:
That was the most important part (beyond using a resistor), so you're on the right track!

To understand exactly why you need one resistor per LED I'll have to delve into some background, it's relatively simple though.

To start off with, an LED has a voltage below which it will simply not turn on (or will only just basely sort of turn on). This is the "forward voltage". What that means we can leave for later, suffice to say that an LED with a forward voltage of 2.2 volts requires 2.2 volts to turn on.

Here's the issue: Once above it's minimum forward voltage, an LED has essentially zero resistance, that means that a LOT of current flows through it, quickly overheating the LED (and/or the microcontroller sourcing the current!) and frying it.
LED's have a second important number, their current rating. A typical red LED has a forward voltage of 1.8v and a current rating of 10-20 milliamps (ma).
If you tell the Arduino to turn a pin HIGH it puts out five volts (definitely over 1.8v!) and far more than 10-20ma of current, exactly how much I don't know, but a lot more than that.
Hence we need a resistor to provide some resistance and prevent excessive current flow (that's what resistors "resist", current flow).
That's the simple part, now for slightly more complexity :D

Once above the forward voltage of a LED the current flow is responsible for the brightness of the LED. More current = brighter LED. Less current = dimmer LED.

Ok, now we finally get to the answer to the question of why you need one resistor per LED!
Say you have two identical LEDs, they both want 1.8v and they both want 10ma of current.
You connect the positive leads of the LEDs to a pair of Arduino output pins, you then connect the negative leads to ground via a single resistor sized for 10ma of current.

Turn one LED on, and it's nice and bright!
Turn both LEDs on and they both turn on, but they are dim.
Why? Because they have to share the 10ma of current! The result is that each LED only gets 5ma, and hence is dim.

Ok that didn't work, lets size the resistor for 20ma so the LEDs are bright when both are turned on!
Downside: If you only turn one LED on it gets 20ma, rather more than the 10ma it is rated for and it goes POP! RIP LED.


You can safely do the first if you don't mind dim LEDs, it won't hurt anything.
Alternatively you can connect the positive lead of the first LED to the Arduino, the negative lead to the next LED's positive lead, that LED's negative to the next positive, and so on. Add the forward voltages together to get the total voltage you need, and size the resistor for whatever an individual LED wants.
The downside is that you can only turn on all the LEDs or none of the LEDs with this wiring scheme.

There are other schemes known as "multiplexing" which I expect you'll get to eventually in your class, they're a bit of a headache.


EDIT:
If you want to be that annoying guy that does more than the instructor asks for, the stuff in the spoiler box might be fun.
Code:
//Workshop 1 Task 2
int LEDPin = 0;

int pulseRate = 0; //0-10 where 0 is off and 10 is on

void setup() {
//initialise the digital pin as an output
pinMode(LEDPin, OUTPUT);
}


void loop() {
  if (pulseRate == 10) {
    digitalWrite(LEDPin, HIGH);
    delay(2000);
  }
  else if (pulseRate == 0){
    digitalWrite(LEDPin, LOW);
    delay(2000);
  }
  else {
    delay(pulseRate*100);
    digitalWrite(LEDPin, LOW);
    delay(pulseRate*100);
    digitalWrite(LEDPin, HIGH);
  }
  pulseRate++;
  if (pulseRate == 11){
    pulseRate = 0;
  }
}

Pretty simple change, see if you can figure out what it does, then stuff it into the arduino and see if you're right :D

Question, why do you have delay(2000); on the if (pulseRate == 10) statement?

Remembering some programming I've done in the past, pulseRate++ means increase it by 1....so I'm guessing this loops through each possibility until it gets to 10...then stays on? Or is that why you have the delay(2000) so it stays on for 2 seconds then goes up to 11 which gets turned into 0 and goes off?
 
The delays are in there so that it stays turned off and stays turned on for a bit, otherwise it would go through those in a fraction of a millisecond.

The pulseRate++ does exactly what you suspect, as does the program.
 
but what if we make it ==10?
Will it just stay on permanently? Or will it enter the loop and move up to 11, then change to 0 and switch off? (10 is supposed to keep it on).

Next question:
(lol only a few more questions today I promise)
taj67s.jpg

Is that OK for connecting 3 LEDs? I'm not sure if it makes a circuit. I was just reading the wiki on breadboards but I'm confused as to how all the terminals (if that's the correct word?) are connected (or disconnected).
 
If you take the pulseRate++ bit out it'll behave exactly how your instructor wants, with a starting value of 0 being permanetly off and a starting value of 10 being perminatly on.
If you leave the pulseRate++ in place it will loop around.

Breadboard wise, Fritzing is giving you a hint when it puts a green box around a row of holes (terminals is a correct term too I think).
Attached is a scribbled on screenshot, the red lines show the internal connections.
The left-right holes on the edges of the breadboard are connected like in the picture on that type of breadboard, on the ones with +/- printed on it and red and blue lines down the sides the side terminals are all connected together.
The circuit you put together won't work, as only the rightmost terminal of the rightmost resistor is actually attached to the arduino.

If you know the correct resistor to use for one LED you can use that same resistor for connecting LEDs in series (pin3 to resistor, resistor to LED1+, LED1- to LED2+, LED2- to LED3+, LED3- to GND).
 
If you take the pulseRate++ bit out it'll behave exactly how your instructor wants, with a starting value of 0 being permanetly off and a starting value of 10 being perminatly on.
If you leave the pulseRate++ in place it will loop around.

Breadboard wise, Fritzing is giving you a hint when it puts a green box around a row of holes (terminals is a correct term too I think).
Attached is a scribbled on screenshot, the red lines show the internal connections.
The left-right holes on the edges of the breadboard are connected like in the picture on that type of breadboard, on the ones with +/- printed on it and red and blue lines down the sides the side terminals are all connected together.
The circuit you put together won't work, as only the rightmost terminal of the rightmost resistor is actually attached to the arduino.

If you know the correct resistor to use for one LED you can use that same resistor for connecting LEDs in series (pin3 to resistor, resistor to LED1+, LED1- to LED2+, LED2- to LED3+, LED3- to GND).

Your pic doesn't seem to be attached but regardless I think I've got it now (the rows of 5 terminals are connected but they're not connected to the ones each side of them).
rms0ic.jpg

OK hopefully last question for a while: we're tasked with making the different LEDs flash at different rates. It is suggested that we use millis().
Wait now I'm very confused, if they're all in one circuit I don't know how it could be done....I guess they're supposed to be connected to 3 seperate outputs on the Arduino board.....but then how do you ground 3 different things?
 
You're going to need some jumper wires for your breadboard, take the GND arduino pin and send it to the breadboard, now that breadboard row is your ground source. You can ground as many LEDs there as you want to (at this point, trying to ground 200 LEDs to the arduino is a bad idea).

Now now do what you did with the single LED, LED+ pin to arduino pin3, LED- pin to a resistor, and the other end of the resistor to your GND row on the breadboard.
Now in a different row of the breadboard put a second LED, attach it's LED+ pin to pin4 on the arduino, it's LED- to a second resistor, and that resistor's other leg to the same GND.
Do the same for the third LED.
 
You're going to need some jumper wires for your breadboard, take the GND arduino pin and send it to the breadboard, now that breadboard row is your ground source. You can ground as many LEDs there as you want to (at this point, trying to ground 200 LEDs to the arduino is a bad idea).

Now now do what you did with the single LED, LED+ pin to arduino pin3, LED- pin to a resistor, and the other end of the resistor to your GND row on the breadboard.
Now in a different row of the breadboard put a second LED, attach it's LED+ pin to pin4 on the arduino, it's LED- to a second resistor, and that resistor's other leg to the same GND.
Do the same for the third LED.

Ahhh you send the Arduino ground to the breadboard.
Thank you very much for your help...I have that class today so I'm hopefully going to have caught up now. I'll likely have more questions in future though.
 
How's the class going?

Hey, it's going fairly well. I was doing a question where we installed a button on the breaboard and when pressed it would light up an LED. Honestly, I got help from somebody and didn't really understand what happened so I'll need to lull over that code and circuit for quite a while because the next question is to have several LEDs light up in order when the button is pressed :cry:
 
They're ramping things up, that's good practice though, lots of different ways to accomplish it too.

Starting hints: You're going to want two sections in the code (both in void loop, but separate portions).
One section to count (and debounce, have they talked about debouncing?) button pushes and store that data somewhere.

The second section the button push number, and turn the proper number of LEDs on.


Actually, if you can tell me the assignments that'd be great, I'll do 'em too. It'll be good practice for me. I'm totally self-taught (well, self and reading forums), so it's likely that I've missed some things.
 
They're ramping things up, that's good practice though, lots of different ways to accomplish it too.

Starting hints: You're going to want two sections in the code (both in void loop, but separate portions).
One section to count (and debounce, have they talked about debouncing?) button pushes and store that data somewhere.

The second section the button push number, and turn the proper number of LEDs on.


Actually, if you can tell me the assignments that'd be great, I'll do 'em too. It'll be good practice for me. I'm totally self-taught (well, self and reading forums), so it's likely that I've missed some things.

They have not spoken about debounce yet...so I have no idea about that lol.

OK after the LEDs lighting up in sequence we have to changet he code so that depending on how long you hold the button, it will light each subsequent one up.
Then using more buttons, have them light up in different orders and time lengths.

The next task is to install a little speakers and have various buttons be used like a keyboard. Then to have it play a score downloaded from the net.

After that we deal with fans and potentionmeters. We're to change the rate of the fan and the number of LEDs that switch on by adjusting the ADC value of the potentionmeter (no idea what any of that means).

After that we use a thermistor to make a temperature reader.

I'm scared to read any further....it's starting to sound really complex.
 
It all seems to build on itself, it'll make more sense the further in you get.

One key thing: Even when copying someone else's example, don't copy+paste. Instead type it yourself. It seems silly, but if you type it yourself you'll have a lot easier time remembering it and how it works.
 
It all seems to build on itself, it'll make more sense the further in you get.

One key thing: Even when copying someone else's example, don't copy+paste. Instead type it yourself. It seems silly, but if you type it yourself you'll have a lot easier time remembering it and how it works.

Yeah I would never copy and paste. The University does pretty extensive checking of plagiarism too.
 
Quick question:
From the basic example on the Arduino website where you either push the button and have the digital pin 2 receive an input of 5V or don't push the button and it receives 0? Or something?

34pe7u1.jpg

I don't understand the flow of current from the diagram. When the button is pushed, does it bridge diagonally?

void setup() {
Serial.begin(9600);
pinMode(2, INPUT);
}

void loop() {
int sensorValue = digitalRead(2);
Serial.println(sensorValue, DEC);
}

Because they set pinMode(2, INPUT); does that mean the current doesn't start from there but rather goes towards there?

And why the big wires on the far right?
 
Back