analogWrite() Causes my code to freeze

Hi
I am creating a basic program to operate my 3D printed robot. I have some LEDs that I want to fade on/off, but every time the program gets to the analogWrite() the program freezes. No serial output, no updates in the state of the pins... it just remains in this stateuntil I reset the program. I know 100% it's the analogWrite() because when I comment it out everyting works fine. I'm aware that using certain libraries may effect pwm pins. I'm using the Servo.h and Ultrasonic.h libraries. The pin I'm trying to write to is pin 11 on an Arduino Nano.
Any help would be appreciated.

Code posted in so called code tags would be appreciated.

Your post was MOVED to its current location as it is more suitable.

No way to help without seeing your code. I use analogs on the Nano all of the time so I'm guessing it is a code related issue unless you have a flaky Nano.

Here's the full code. It's just a basic framework for what I need evetually, but I need to sort the issue out...

 //Include the following libraries
#include <Servo.h>
#include <Ultrasonic.h>

//Declare constants for GPIO pins
const int leftEnable = 5;
const int leftCtrl1 = 7;
const int leftCtrl2 = 8;

const int rightEnable = 6;
const int rightCtrl1 = 9;
const int rightCtrl2 = 10;

const int buzzerPin = 4;
const int ledPin = 11;
const int tiltSens = 2;
const int LDR = A1;


unsigned long timer = 0;
unsigned long currentTime = 0;
int aLightVal;
int lightVal = 0;
Ultrasonic RangeSensor(12, 13);


int range;
int turnDirection;
int randomTurn;
int randomTilt;
int randomNote;
int randomDuration;
int command;

//Zero servo angle
const int zeroAngle = 70;

//Declare the Servo and ultrasonic range finder being used
Servo headServo;

void setup() {
  //Initialize the servo to pin 3
  headServo.attach(3);
  headServo.write(zeroAngle);

  //Commence serial communication at 9600 baud
  Serial.begin(9600);
  
  pinMode(ledPin, OUTPUT);
  pinMode(leftCtrl1, OUTPUT);
  pinMode(leftCtrl2, OUTPUT);
  pinMode(rightCtrl1, OUTPUT);
  pinMode(rightCtrl2, OUTPUT);
  
 headServo.write(zeroAngle);

digitalWrite(ledPin, HIGH);
delay(150);
digitalWrite(ledPin, LOW);
delay(150);
digitalWrite(ledPin, HIGH);
delay(150);
digitalWrite(ledPin, LOW);
}

void loop() {

if(Serial.available() == 1){
 command = Serial.parseInt();
 Serial.println(command);
}

if(command == 1){
  
  randomTurn = random(700, 2501);
  randomTilt = random(50, 91);
  turnDirection = random(0, 2);
  randomNote = random(1, 4);
  randomDuration = random(1, 4);
  range = RangeSensor.read(); 

  //Set both motors to full speed
  analogWrite(leftEnable, 255);
  analogWrite(rightEnable, 255);
  //Move forward if the path is clear, else reverse for half a second
  if (range > 15) {
    digitalWrite(leftCtrl1, HIGH);
    digitalWrite(leftCtrl2, LOW);
    digitalWrite(rightCtrl1, HIGH);
    digitalWrite(rightCtrl2, LOW);
  }
  else {
     
    headServo.write(randomTilt);
    digitalWrite(leftCtrl1, LOW);
    digitalWrite(leftCtrl2, HIGH);
    digitalWrite(rightCtrl1, LOW);
    digitalWrite(rightCtrl2, HIGH);
    delay(500);
    headServo.write(zeroAngle);
  
    //Turn away from the obstacle with random angle and direction   
    if (turnDirection == 0) {
      digitalWrite(leftCtrl1, LOW);
      digitalWrite(leftCtrl2, HIGH);
      digitalWrite(rightCtrl1, HIGH);
      digitalWrite(rightCtrl2, LOW);
    }
    else {
      digitalWrite(leftCtrl1, HIGH);
      digitalWrite(leftCtrl2, LOW);
      digitalWrite(rightCtrl1, LOW);
      digitalWrite(rightCtrl2, HIGH);

    }
    delay (randomTurn);
  }
}
else{
    digitalWrite(leftCtrl1, LOW);
    digitalWrite(leftCtrl2, LOW);
    digitalWrite(rightCtrl1, LOW);
    digitalWrite(rightCtrl2, LOW);
}
  


//Beginning of light fader
timer = millis();
aLightVal = analogRead(LDR);
aLightVal = map(aLightVal, 0, 600, 0, 100);

//Check to see if the ambient light is below threshhold
//If LED is not yet at target brightness, fade every 4 milliseconds
if (aLightVal < 40){
 if (timer - currentTime > 4){
  if (lightVal < 255){

   lightVal = lightVal + 1;
   currentTime = timer; 
  }
 }
}

if (aLightVal >= 40){
if (timer - currentTime > 4){
  if (lightVal > 0){

  lightVal = lightVal - 1;
  currentTime = timer;
  }
}
analogWrite(ledPin, lightVal); //This is what cases the program to freeze

}

The code that you posted is incomplete. Where does the loop() function end ?

What is the value of lightVal when the program freezes ?
I assume that you have a current limiting resistor in series with the LED

1 Like

Writes an analog value (PWM wave) to a pin. Can be used to light a LED at varying brightnesses or drive a motor at various speeds. After a call to analogWrite() , the pin will generate a steady rectangular wave of the specified duty cycle until the next call to analogWrite() (or a call to digitalRead() or digitalWrite() ) on the same pin.

analogWrite() - Arduino Reference

It could be that the PWM and servo are mixing with each other. Have you tried using different pins or using the servo library to modulate the LED's brightness?

  1. The code is complete
  2. The moment lightVal is no longer 0 (when it gets incremented to 1 when the ambient light is below threshold) it causes the freeze.
  3. Yes I do have a resistor in series with the LED

I have not tried that... the problem is that It all seemed to work when building the circuit on a breadboard. Now it's all hard wired into my custom PCB so using a different pin is no longer an option :frowning:

If all else fails I'll turn the LEDs on with a digitalWrite(), but that doesn't look nearly as elegant.

Do you speculate that

those instructions will take longer then 4 milli seconds?

Do you really intend the analogWrite() to be controlled by if (aLightVal >= 40) ? In the posted code when you increment lightVal you don't write anything.

Steve

No it's definitely the analogWrite() itself, because if I write it with a static value like 255 the same thing happens.

I do. Because the if() is not a loop, it simply increments/decrements the value and then writes it afterwards. It worked perfectly when I took the LED fader part out and pasted it in a new blank sketch.

try pruning back other parts of the code to see where the analog write conflicts with something else

I am willing to bet that the code you posted is not complete.

I strongly suspect that you did not copy the final } of the loop() function when you copy/pasted it here. If I am wrong then please tell me where the loop() function ends

The easiest way to post code here is to make sure that no text is selected in the IDE then right click in the IDE edit window and select "Copy for forum" and paste the copied code into a post here. The code tags will have been added automatically when the code was copied

1 Like