Pages: [1]   Go Down
Author Topic: Code not functioning correctly (inputs toggling without change in voltage)  (Read 497 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Jr. Member
**
Karma: 0
Posts: 69
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The code and setup I am working with are meant to do is control a RBG LED through a On/Off/On Switch and 2 potentiometers, the potentiometers control brightness and color and the switch toggles the program between keeping a solid color (chosen by the potentiometer) being off and changing colors automatically (sort of a light show)

now as for the problem, when I put this code into my arduino and load it up, everything works splendidly, but then when I put it on my own microcontroller circuit all hell breaks loose, well that might be a slight exageration.. what happens is the program keeps thinking that it should switch to the light show mode even when no power is given that input or if its in solid color mode, it will either blink (going from off to the show in intervals about one second) or if it is in solid color mode it will switch from one mode to another in similar intervals. the show functions as it should once the input is ACTUALLY recieving power.

A description of my setup, I'm using an atmega 328 with an arduino bootloader, programmed by simply putting it in the arduino uno and then taking it out once its programmed, for power regulation i am using a 100 uf capacitor with a .01 uf capacitor to filter out undesirable frequencies, and for the clock i am using a 16mhz crystal with 2 22pf capacitors. I've been killing myself over this for days, if anyone has any ideas, you'll be my savior..

My code will follow below
Logged

Offline Offline
Jr. Member
**
Karma: 0
Posts: 69
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
//===============================================================================================
const int  buttonLightPin = A3; //sets buttonLight to input 12
const int  buttonShowPin = A5; //sets buttonShow to input 13
const int brightnessPotPin = A0; //sets the pot output to A0
const int colorPotPin = A1; // sets the color during solid light
int brightnessPotState; //variable for storing the value of the brightness pot
float brightnessSet =1; // variable for storing the brightness level
int buttonState = 2; // variable for storing the mode that the devvice is in
// 0 is for off, 1 is for light show and 2 is for solid color
int PIN_RED = 3; // input for red; red jumper, white cord
int PIN_GREEN = 5; // input for green; green jumper
int PIN_BLUE = 9; //input for blue; red jumper, yellow cord
int counter;
int numColors = 255;
int animationDelay = 15; //adjustable speed of animation
float brightness = 0; // default brightness level
int lag = 15;
int showCounter = 0;
int lightCounter = 0;
int offCounter = 0;

//===============================================================================================

void setup()
{
  Serial.begin(9600);
  pinMode(buttonLightPin, INPUT);
  pinMode(buttonShowPin, INPUT);
  pinMode(brightnessPotPin, INPUT_PULLUP);
  pinMode(colorPotPin, INPUT_PULLUP);
  pinMode(PIN_RED, OUTPUT);
  pinMode(PIN_BLUE, OUTPUT);
  pinMode(PIN_GREEN, OUTPUT);
}

//===============================================================================================

void loop()
{
  Serial.print("Begin");
  float colorNumber = counter > numColors ? counter - numColors: counter;
  float saturation = 1; // Between 0 and 1 (0 = gray, 1 = full color)
  float hue = (colorNumber / float(numColors)) * 360;
  float brightness = setBrightness();
  long color = HSBtoRGB(hue, saturation, brightness);
  int red = color >> 16 & 255;
  int green = color >> 8 & 255;
  int blue = color & 255;
  buttonState = setButtonState(); //function below for determining button state
  Serial.print("  MODE: ");
  if(buttonState == 1) // if buttonstate is 1, light show will commence
  {
    showCounter++;
    if(showCounter > 10)
    {
      lightCounter = 0;
      offCounter = 0;
      Serial.print("SHOW");
      setColor(red, green, blue); //writes the color chosen by HSBtoRGB
      Serial.print("  Red: ");
      Serial.print(red);
      Serial.print("\t");
      Serial.print("  Green: ");
      Serial.print(green);
      Serial.print("\t");
      Serial.print("  Blue: ");
      Serial.print(blue);
      counter = (counter + 1) % (numColors * 2); // sets counter to increment the color changes
      delay(animationDelay);
    }
  }
  else if(buttonState == 2) // if buttonstate is 2, LEDs will emit solid colors determined by the colorPotPin
  {
    lightCounter++;
    if(lightCounter > 10)
    {
      showCounter = 0;
      offCounter = 0;
      Serial.print("SOLID COLOR");
      solidColor(brightness);
    }
  }
  else if(buttonState == 0) // if buttonstate is 0, no light will emit
  {
    offCounter++;
    if(offCounter > 10)
    {
      lightCounter = 0;
      showCounter = 0;
      Serial.print("OFF");
      off();
    }
  }
  Serial.print("\t");
  Serial.println("END");
}

//===============================================================================================

float setBrightness() // finds brightness from pot
{
  float brightnessPotState; //variable for storing the value of the brightness pot
  brightnessPotState = analogRead(brightnessPotPin); //reads brightness
  Serial.print("  Brightness Pot: ");
  Serial.print(brightnessPotState);
  if(brightnessPotState <= 1000) // converts pot input(0-1023) into a percentage
    //i ignored the final 23 values and lumped it into a solid 100%
  {
    brightnessSet = brightnessPotState/1000;
  }
  else
  {
    brightnessSet = 1;
  }
  return brightnessSet; // returns the percentage brightness
}

//===============================================================================================


int setButtonState() //toggles between Show, Light, and off
{
  int buttonShow; // variable storing the value of the buttonShowPin
  int buttonLight; //variable storing the value of the buttonLightPin
  int x;
  buttonShow = digitalRead(buttonShowPin);
  buttonLight = digitalRead(buttonLightPin);
  Serial.print("\t");
  Serial.print ("  Button Show: ");
  Serial.print (buttonShow);
  Serial.print ("\t");
  Serial.print ("  Button Light: ");
  Serial.print (buttonLight);
  Serial.print ("\t");
  if (buttonShow == HIGH)
  {
    return(1);
  }
  else if( buttonLight == HIGH)
  {     
    return(2);
  }
  else if(buttonLight == LOW && buttonShow == LOW)
  {
    return(0);
  }
}
//===============================================================================================

void off() // turns off all LEDs
{
  analogWrite(PIN_RED, LOW);
  analogWrite(PIN_GREEN, LOW);
  analogWrite(PIN_BLUE, LOW);
}

//===============================================================================================

void solidColor(float brightness) //sets the color for light mode
{
  int redSolid;
  int blueSolid;
  int greenSolid;
  float colorPotState; //varible for storing the value of the color pot
  colorPotState = analogRead(colorPotPin);
  Serial.print("Color Pot State: ");
  Serial.print(colorPotState);
  if (colorPotState < 341) //first 1/3 of the pots potential value
  {
    colorPotState= (colorPotState * 3)/4; // converts pot value into a 0-255 range
    redSolid = (256 - colorPotState) * brightness; //full to 0
    greenSolid = colorPotState * brightness; // 0 to full
    blueSolid = 1; //off
  }
  else if(colorPotState < 682) //second 1/3 of the pots potential value
  {
    colorPotState= ((colorPotState-341) * 3)/4; // converts pot value into a 0-255 range
    redSolid = 1; //off
    greenSolid = (256 - colorPotState) * brightness; //full to 0
    blueSolid = colorPotState * brightness; // 0 to full
  }
  else // Remainder of the pots value
  {
    colorPotState= ((colorPotState-683) * 3)/4; // converts pot value into a 0-255 range
    redSolid = colorPotState * brightness; // 0 to full
    greenSolid = 1; //off
    blueSolid = (256 - colorPotState) * brightness; //full to 0
  }
  Serial.print("  Red: ");
  Serial.print(redSolid);
  Serial.print("\t");
  Serial.print("  Green: ");
  Serial.print(greenSolid);
  Serial.print("\t");
  Serial.print("  Blue: ");
  Serial.print("\t");
  Serial.print(blueSolid);
  analogWrite(PIN_RED, redSolid); //set red level based on pot value
  analogWrite(PIN_GREEN, greenSolid); //set green level based on pot value
  analogWrite(PIN_BLUE, blueSolid); //set blue level based on pot value
}

//===============================================================================================

void setColor (unsigned char red, unsigned char green, unsigned char blue) //sets the color for each instance of the show
{
  analogWrite(PIN_RED, red); // set red leve
  analogWrite(PIN_GREEN, green); // set red leve
  analogWrite(PIN_BLUE, blue); // set red leve
}

//===============================================================================================

long HSBtoRGB(float _hue, float _sat, float _brightness) //interprets and changes the color
{
  float red = 0.0; // initialize local variables
  float green = 0.0;
  float blue = 0.0;

  if (_sat == 0.0) // if there is no saturation, the color will turn off
  {
    red = _brightness;
    green = _brightness;
    blue = _brightness;
  }
  else
  {
    if (_hue == 360.0)  // when hue reaches 360, it resets to 0
    {
      _hue = 0;
    }

    int slice = _hue / 60.0; // initializes varible to break the process into 6 "slices"
    float hue_frac = (_hue / 60.0) - slice; // each slice is one 6th of the process

    float aa = _brightness * (1.0 - _sat); // sets the 3 different functions for increasing and decreasing color based on saturation, brightness, and hue
    float bb = _brightness * (1.0 - _sat * hue_frac);
    float cc = _brightness * (1.0 - _sat * (1.0 - hue_frac));

    switch(slice) //depending on which slice the program is in, it will pick one of these options to adjust the color
    {
    case 0:
      red = _brightness;
      green = cc;
      blue = aa;
      break;
    case 1:
      red = bb;
      green = _brightness;
      blue = aa;
      break;
    case 2:
      red = aa;
      green = _brightness;
      blue = cc;
      break;
    case 3:
      red = aa;
      green = bb;
      blue = _brightness;
      break;
    case 4:
      red = cc;
      green = aa;
      blue = _brightness;
      break;
    case 5:
      red = _brightness;
      green = aa;
      blue = bb;
      break;
    default:
      red = 0.0;
      green = 0.0;
      blue = 0.0;
      break;
    }
  }

  long ired = red * 255.0; // set red
  long igreen = green * 255.0; // set gren
  long iblue = blue * 255.0; // set blue

  return long((ired << 16) | (igreen << 8) | (iblue)); // return colors
}
//===============================================================================================
Logged

NL
Online Online
Newbie
*
Karma: 1
Posts: 30
Tech Tinkerer
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Sounds like the input pin is floating when the button is not pressed. I assume (as the code does not turn on the internal pullup on A5) that there is a external pull-down resistor on that pin?

Hope this helps,
Guido
Logged

NSW Australia
Offline Offline
Faraday Member
**
Karma: 80
Posts: 3238
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

for power regulation I am using a 100 µf capacitor with a .01 µf capacitor to filter out undesirable frequencies,

Just as a matter of curiosity, what are you using as a regulator?

And ...

Why are you defining the analog inputs as INPUT_PULLUP (that might actually work, but I don't know whether it does; you may have researched it more closely), but not the pushbutton inputs?
« Last Edit: December 26, 2013, 07:12:37 am by Paul__B » Logged

Austin, TX
Offline Offline
Faraday Member
**
Karma: 71
Posts: 6136
Baldengineer
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Why are you defining the analog inputs as INPUT_PULLUP (that might actually work, but I don't know whether it does; you may have researched it more closely), but not the pushbutton inputs?
Yes you can turn on the pull-up resistor for an analog input.  However, any analog readings that are taken, need to take into account that now a voltage divider is setup on that pin.
Logged

Capacitor Expert By Day, Enginerd by night.  ||  Personal Blog: www.baldengineer.com  || Electronics Tutorials for Beginners:  www.addohms.com

Offline Offline
Jr. Member
**
Karma: 0
Posts: 69
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Why are you defining the analog inputs as INPUT_PULLUP (that might actually work, but I don't know whether it does; you may have researched it more closely), but not the pushbutton inputs?
How do I take it into account? i changed all of the analog inputs to INPUT_PULLUP and now my serial output is telling me that all both modes are active when neither are recieving power?
Quote
Just as a matter of curiosity, what are you using as a regulator?

And ...

Why are you defining the analog inputs as INPUT_PULLUP (that might actually work, but I don't know whether it does; you may have researched it more closely), but not the pushbutton inputs?
I assume you mean besides the capacitors? a switching 5v power supply i bought online (https://www.sparkfun.com/products/8269), my use of input pullup was based off of advice from someone on this forum when designing my code, im not 100% sure..
Quote
Sounds like the input pin is floating when the button is not pressed. I assume (as the code does not turn on the internal pullup on A5) that there is a external pull-down resistor on that pin?
no, there is no internal or external pullup/ pulldown on that pin, but as I said above turning it on made both inputs think they're recieving power..
Logged

Austin, TX
Offline Offline
Faraday Member
**
Karma: 71
Posts: 6136
Baldengineer
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

no, there is no internal or external pullup/ pulldown on that pin, but as I said above turning it on made both inputs think they're recieving power..
That's how pull-up works (internal or external).  They "pull" the pin "up" to whatever voltage their connected to.  In this case it is 5volts.
Logged

Capacitor Expert By Day, Enginerd by night.  ||  Personal Blog: www.baldengineer.com  || Electronics Tutorials for Beginners:  www.addohms.com

Offline Offline
Jr. Member
**
Karma: 0
Posts: 69
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
That's how pull-up works (internal or external).  They "pull" the pin "up" to whatever voltage their connected to.  In this case it is 5volts.
So would I use a pull down resistor then?.. Or is there someway to make it work as an input with the pullup?
Logged

Austin, TX
Offline Offline
Faraday Member
**
Karma: 71
Posts: 6136
Baldengineer
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

If the pin is left floating when you are using a potentiometer, you are have It wired wrong.

Maybe post a schematic of what you are doing.
Logged

Capacitor Expert By Day, Enginerd by night.  ||  Personal Blog: www.baldengineer.com  || Electronics Tutorials for Beginners:  www.addohms.com

Offline Offline
Jr. Member
**
Karma: 0
Posts: 69
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

It's not the potentiometer it's the switch, I'll use a jumper to simulate switch inputs but it doesn't make a difference, it thinks both inputs are on when using the pull-up resistor, I'm not home so I can't draw up a schematic right now but if u still need it when I get home ill work it up
Logged

Austin, TX
Offline Offline
Faraday Member
**
Karma: 71
Posts: 6136
Baldengineer
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

It's not the potentiometer it's the switch

Again, that's how pull-ups work.  The pin is "HIGH" when there is no connection (or the switch is off) and the pin is "LOW" when the switch is closed.  The code doesn't care if "high" means "on" or "off".
Logged

Capacitor Expert By Day, Enginerd by night.  ||  Personal Blog: www.baldengineer.com  || Electronics Tutorials for Beginners:  www.addohms.com

Offline Offline
Jr. Member
**
Karma: 0
Posts: 69
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

So I'm sorry but how do I close the pin? Again sorry if this is obvious stuff but I'm not very familiar with these concepts
Logged

Austin, TX
Offline Offline
Faraday Member
**
Karma: 71
Posts: 6136
Baldengineer
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

The switch "opens" and "closes".  So when it is "open" the pin is left floating unless "pulled-up" by a resistor.

When the switch is "closed" it connects the pin to ground, making it a low.

Here's some videos and explanations that might help:
http://www.baldengineer.com/tutorials/arduino-pull-ups/
Logged

Capacitor Expert By Day, Enginerd by night.  ||  Personal Blog: www.baldengineer.com  || Electronics Tutorials for Beginners:  www.addohms.com

NSW Australia
Offline Offline
Faraday Member
**
Karma: 80
Posts: 3238
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

There seems to be some confusion here!

CMOS inputs - as on the Arduino - are very high impedance, which means that unless connected to something, the voltage they see could be absolutely anything (between 0 and Vcc, since internal diodes prevent the voltage going outside that range) and can or will present a fairly random digital state.

When using a switch, you need to arrange it so that when the switch is on, the input is at one particular logic level, and when it is off, the input goes to the other logic level.  The preferred way of doing this is to have the switch (button) connect from the input to ground, and have a resistor "pull-up" from the input to Vcc so that when the switch is pressed, the input reads low, when it is not pressed, the resistor pulls the input up and the input reads high.

Such a resistor is provided internally in the Arduino chip and is enabled on an input when that port is written to as "high" even though it is actually defined as an input.  When the switch pulls the input low, some small current (about 500 µA) necessarily flows from the resistor, but that is no particular problem.  You need then to write your code understanding that a high corresponds to the button not pressed, and a low to it being pressed.

Enabling that pull-up on a port used as an analog input effectively puts a 10k ohm resistor between the port and Vcc, which is then in your case, between the wiper of the potentiometer and the end connected to Vcc and will tend to bias the voltage read from the potentiometer, upward making it non-linear.  On the other hand, should the potentiometer for whatever reason be not connected, it will reliably substitute a reading near to maximum, which may be a useful safety feature.
« Last Edit: December 26, 2013, 04:13:46 pm by Paul__B » Logged

Offline Offline
Jr. Member
**
Karma: 0
Posts: 69
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Its fixed!! thank you so much paul, your explanation did help, Ive set the code to interpret high inputs as off and ive wired the switch to the ground, when the ground is applied to either input it turns it to that mode with no blinking or switching! thank you so much!
Logged

Pages: [1]   Go Up
Jump to: