AnalogWrite problems

Hello!

As a fairly rookie programmer, I have been experiencing some persistent problems with my latest program. I want to make a function that fades a LED in in a few different places in my code, but I can't even get to dim it properly using analogWrite somehow. And I can't seem to figure out what's wrong.

For some reason, analogWrite(255) turns the led on, so far everything normal, but any value below 255 turns the led off, as if it were a digital signal.

I can run the normal fade code to make the led fade without any problems, so I'm guessing it's probably a problem with the rest of my code?

Here's my code. Any help or tips would be most welcome!

/*This code is for the hackable guardian robot project from Thingiverse
 * 
 * Besides the eye led, the head-turn servo and led string in the body,
 * it has been edited to support a sound sensor as wel. This allows the guardian robot to react to loud souds  
 * in a more or less game-accurate way, by waking up, looking around and falling back into a standby modus. 
 *
 *Switches between the original 'permanently on' and responsive mode using a pushbutton.
 */
 
#include <Servo.h>

Servo myservo;                          // create servo object to control a servo

int MIN = 0;                            // Set servo values, control the guardian's head turn angles
int MAX = 180;
int NTRL = 90; 

const int minSound = 0;                 //sound sensitivity of the sound sensor. A higher number will respond at slighter sounds.

const int switchButton = 2;             // Mode-switch pin
const int soundSensor = A0;             // Sound sensor pin
const int bodyLED = 9;                  // Body led pin
const int eyeLED = 10;                  // Eye led  pin
                 // Set servo to pin 8;

boolean switchState = true;             // the current state of the mode-switch pin
int reading;                            // the current reading from the input pin
int previous = 0;                       // the previous reading from the input pin
long time = 0;                          // the last time the mode-switch was toggled
long debounce = 200;                    // the debounce time, increase if the output flickers

unsigned long t;                        // Head-turn timer for active mode
int lastLookTime = 0;                   // Time of last head-turn
              
boolean active = false;                 
int i;


int fadeIn()
{
  analogWrite(bodyLED,255);   // <------------------------ HERE'S WHERE MY PROBLEM COMMAND IS DECLARED. 
  delay (1000);               //ANALOGWRITE(BODYLED,<255)SOMEHOW TURNS OFF THE LED INSTEAD OF DIMMING IT
}


//-------------------------------------------------------------------------------------------------------------------------

void setup() 
{
  Serial.begin(9600);
  myservo.attach(6);                  
  pinMode(soundSensor,INPUT); 
  pinMode(switchButton, INPUT);
  pinMode(bodyLED, OUTPUT);
  pinMode(eyeLED, OUTPUT); 
}

//------------------------------------------------------------------------------------------------------------------------

void loop() 
{
 int sensorValue = analogRead(soundSensor);                   // Read the sound sensor
 
 reading = digitalRead(switchButton);                             //Operates the switch between the fully active and awoken/decayed state     
  if (reading == true && previous == false &&                     // Toggles between switchState == TRUE (fully active mode) and switchState == FALSE (decayed/awoken mode) every time the button is pushed
  millis() - time > debounce) 
  { 
    if (switchState == true)
      switchState = false;
    else
      switchState = true;
    time = millis();    
  }
  previous = reading;



  if (switchState == true)                                       //FULLY ACTIVE (when switch button pushed once)
  {
     if (active == false)
      {
        fadeIn();                         // <----------------- AND MY PROBLEM FUNCTION CALLLED HERE... 
        digitalWrite (eyeLED,HIGH);                                  // Activates body- and eye leds
        active = true;
      }
                                                                           
     if(random(10) == 0)                                              //Activates and blinks eye led
     { 
      digitalWrite(eyeLED, LOW); 
      delay(random(50, 250));      
      digitalWrite(eyeLED, HIGH); 
     }
     
     t = millis();
        if((t - lastLookTime) > 500)                                  // If more than 1/2 second has passed since last head turn...               
       {
          if(random(10) == 0) 
             {                                                        // There's a 1-in-10 chance...                                                          
              myservo.write(random(MIN, MAX));                        // ...of randomly moving the head in a new direction:
              lastLookTime = t;                                       // Save the head-turn time for future reference
             }
        }                                         
  }



  else if (sensorValue < minSound  && switchState == false)
{                                                               //AWOKEN STATE (temporary active after noise input)
    active = true;
    fadeIn();                             //<--------------------------- AND HERE.
    digitalWrite(eyeLED, HIGH);
    for (int i =0; i<(random(4,10));i++)                             //Determines the 'time' being awake by cycling through a blink                 
      {                    
              digitalWrite(eyeLED, LOW);                             //Makes the eye led blink 
              delay (random(50,250));
              digitalWrite(eyeLED, HIGH);              
              delay(random(300, 1000));

              if(random(0,2) == 0 )                                   // And every other time it goes trough the loop, here's a 50% chance...   
              {                                                       
                myservo.write(random(MIN, MAX));                      // ...of randomly moving the head in a new direction
              }
      } 
}




  else                                                            //DECAYED STATE (off)
  {                                                            
      if (active == true)                                              // if the guardian robot was still active..
      {                                                               // it will turn the servo into neutral mode and turn off leds one by one. If not, it will just do nothing until further input
        myservo.write (NTRL);
        delay (1000);
        digitalWrite (eyeLED, LOW);
        delay (1000);
        analogWrite (bodyLED,1000);
        active = false;
      }
      else 
      {
      }
 }
  
  Serial.print(" status = ");                                     // Print to serial monitor for debugging
  Serial.print(switchState);

  Serial.print("\t Digital = ");
  Serial.println(sensorValue);

  delay(100);                                             
}

How is the LED wired and does it have a current limiting resistor ?

int fadeIn()
{
  analogWrite(bodyLED, 255);  // <------------------------ HERE'S WHERE MY PROBLEM COMMAND IS DECLARED.
  delay (1000);               //ANALOGWRITE(BODYLED,<255)SOMEHOW TURNS OFF THE LED INSTEAD OF DIMMING IT
}

Why is this function named fadeIn when all it does is to write one value ?

      analogWrite (bodyLED, 1000);

1000 ? Interesting !

Please always do a Tools > Auto Format on your code before posting it. This will make it easier for you to spot bugs and make it easier for us to read. If you're using the Arduino Web Editor you will not have access to this useful tool. I recommend you to use the standard IDE instead.

Please remove unnecessary blank lines from your code before posting to the forum. One or two to separate code into logical sections is fine but large spaces for no reason or random blank lines just make for more scrolling when we're trying to read your code.

Which Arduino board are you using?

The LED is wired in series with an 220 ohms resistor, long pin directly to pin 9 on the arduino, short pin to the resistor, then the GND. The standard arduino fade program works just fine.

The reason the function is called FadeIn(); is because i wanted to let it fade a LED on. However, when I couldn't get it to fade no matter what, I stripped it down to just turning the LED on with an analog value and wait a couple of seconds before continuing with the rest of the code. And then I discovered the above problem; it doesn't dim the LED, but instead just turns it off, making fading impossible as well.

The board I'm using is an arduino genuino uno. Thanks for the format tip, here's the cleaned up code. Hope it helps!

#include <Servo.h>

int MIN = 0;                            // Set servo values, these control the guardian's head turn angles and neutral position
int MAX = 180;
int NTRL = 90;
const int minSound = 0;                 //sound sensitivity of the sound sensor. A higher number will respond at slighter sounds.

const int switchButton = 2;             // Mode-switch pin
const int soundSensor = A0;             // Sound sensor pin
const int bodyLED = 9;                  // Body led pin
const int eyeLED = 10;                  // Eye led  pin
// Set servo to pin 8;

boolean switchState = true;             // the current state of the mode-switch pin
int reading;                            // the current reading from the input pin
int previous = 0;                       // the previous reading from the input pin
long time = 0;                          // the last time the mode-switch was toggled
long debounce = 200;                    // the debounce time, increase if the output flickers
Servo myservo;                          // create servo object to control a servo
unsigned long t;                        // Head-turn timer for active mode
int lastLookTime = 0;                   // Time of last head-turn
boolean active = false;                 // Toggles along with active and passive modus, allows functions to be run once when switching between modi, for example turn LEDS on

int fadeIn()
{
  analogWrite(bodyLED, 255);  // <------------------------ HERE'S WHERE MY PROBLEM COMMAND IS DECLARED.
  delay (1000);               //ANALOGWRITE(BODYLED,<255)SOMEHOW TURNS OFF THE LED INSTEAD OF DIMMING IT
}

void setup()
{
  Serial.begin(9600);
  myservo.attach(6);
  pinMode(soundSensor, INPUT);
  pinMode(switchButton, INPUT);
  pinMode(bodyLED, OUTPUT);
  pinMode(eyeLED, OUTPUT);
}

void loop()
{
  int sensorValue = analogRead(soundSensor);                   // Read the sound sensor
  reading = digitalRead(switchButton);                             //Operates the switch between the fully active and awoken/decayed state
  if (reading == true && previous == false &&                     // Toggles between switchState == TRUE (fully active mode) and switchState == FALSE (decayed/awoken mode) every time the button is pushed
      millis() - time > debounce)
  {
    if (switchState == true)
      switchState = false;
    else
      switchState = true;
    time = millis();
  }
  previous = reading;

  if (switchState == true)                                       //FULLY ACTIVE (when switch button pushed once)
  {
    if (active == false)
    {
      fadeIn();                         // <----------------- AND MY PROBLEM FUNCTION CALLED HERE...
      digitalWrite (eyeLED, HIGH);                                 // Activates body- and eye leds
      active = true;
    }
    if (random(10) == 0)                                             //Activates and blinks eye led
    {
      digitalWrite(eyeLED, LOW);
      delay(random(50, 250));
      digitalWrite(eyeLED, HIGH);
    }
    t = millis();
    if ((t - lastLookTime) > 500)                                 // If more than 1/2 second has passed since last head turn...
    {
      if (random(10) == 0)
      { // There's a 1-in-10 chance...
        myservo.write(random(MIN, MAX));                        // ...of randomly moving the head in a new direction:
        lastLookTime = t;                                       // Save the head-turn time for future reference
      }
    }
  }

  else if (sensorValue < minSound  && switchState == false)
  { //AWOKEN STATE (temporary active after noise input)
    active = true;
    fadeIn();                             //<--------------------------- AND HERE.
    digitalWrite(eyeLED, HIGH);
    for (int i = 0; i < (random(4, 10)); i++)                        //Determines the 'time' being awake by cycling through a blink
    {
      digitalWrite(eyeLED, LOW);                             //Makes the eye led blink
      delay (random(50, 250));
      digitalWrite(eyeLED, HIGH);
      delay(random(300, 1000));
      if (random(0, 2) == 0 )                                 // And every other time it goes trough the loop, here's a 50% chance...
      {
        myservo.write(random(MIN, MAX));                      // ...of randomly moving the head in a new direction
      }
    }
  }
  else                                                            //DECAYED STATE (off)
  {
    if (active == true)                                              // if the guardian robot was still active..
    { // it will turn the servo into neutral mode and turn off leds one by one. If not, it will just do nothing until further input
      myservo.write (NTRL);
      delay (1000);
      digitalWrite (eyeLED, LOW);
      delay (1000);
      analogWrite (bodyLED, 1000);
      active = false;
    }
  }
  Serial.print(" status = ");                                     // Print to serial monitor for debugging
  Serial.print(switchState);

  Serial.print("\t Digital = ");
  Serial.println(sensorValue);

  delay(100);
}

analogWrite (bodyLED, 1000);You forgot to clean up that line

Replace your fadeIn() function with this version

void fadeIn()
{
  for (int fade = 0; fade <= 255; fade++ )
  {
    analogWrite(bodyLED, fade);
    delay (50);
  }
  analogWrite(bodyLED, 0);  //turn off the LED
}

What do you see now when you run the program ?

NOTE : using delay() may cause other problems and need to be replaced later, but try this

Servo.h:

  Note that analogWrite of PWM on pins associated with the timer are
  disabled when the first servo is attached.

On an Uno Servo uses Timer1, which is also used for PWM on pins 9 and 10.
Try using another PWM pin (3, 5, 6, 11).

The new fade function in itself didn't work, it just left the LED off, but when I switched the LED to pin 5 it worked like a charm. After I fixed the 'analogWrite(bodyLED,1000);' mistake as well it now works exactly the way I wanted it. Thanks everyone!

when I switched the LED to pin 5 it worked like a charm.

See reply #6