0

Can anybody explain me, why the PWM doesn't work in such a simple example?

Generally, Timer interrupt is being called once per 100 ms and then in the interrupt function the bool flag (state ) is being set. Then in the main loop the flag is checked and when it is 1 (true) several instructions are being executed. Next, PWM is generated and measured via ADC and also displayed on the LCD.

The problem is that the PWM is generated as 0 or sligthly over the 0, even when the value put to the analogWrite is 255 (max of 8 bit). Variable counter is incremented without problems and this value is being put to the analogWrite and despite it the PWM doesn't work.

I don't know, totally, what can be wrong.

Can anybody help me?

 #include<LiquidCrystal.h>
 #include<TimerOne.h>

  LiquidCrystal lcd(52, 50, 48, 46, 44, 42, 40);

  int out = 12; 
  int in = A7; 
  volatile bool state;  

  int counter = 0;
  volatile int y;


  void setup()
  {
    lcd.begin(16, 2);        
    lcd.clear();
    pinMode(out, OUTPUT);
    pinMode(in, INPUT);


    analogReference(DEFAULT);  
    Timer1.initialize(100000);   
    Timer1.attachInterrupt(functionInterrupt);  


     state = 0;
      y = 0;
   }

   void loop() 
   {
     y = analogRead(in);
     y = y / 4; 
     y = y - 128;


    if (state == 1)
    {
      state = 0;

      counter++;
      if (counter > 255)
      //counter = 0;
      counter = 200;

      //state = 0;
     }

      analogWrite(out,counter);

      lcd.home();
      lcd.setCursor(0, 1);
      lcd.print(counter);  
      lcd.setCursor(12,1);
      lcd.print(y);
     }

    void functionInterrupt()
    {
      state = 1;


     }
0

When you use a timer to generate an Interrupt Service Routine (as you do with the TimerOne library) you change the configuration of that timer (in your case timer1). The timer is used by the TimerOne library to provide an interrupt, but also by the microcontroller itself to produce a PWM signal on some pins depending on the timer: in your case (Arduino Mega, timer 1) on the 11 and 12. If you use one of these pins as "analog" output while controlling an ISR with the same timer you won't get the expected output, because the timer isn't any more configured as needed by the PWM generation mechanism but as needed by you (you changed the configuration of the timer in the Timer1.initialize(100000); function call).


So, either you use another PWM pin as output either you use a timer library which uses another timer (or you implement it by yourself).

  • I just edited my own answer because as I wrote it I didn't notice you (the OP) were using an Arduino Mega board (you only wrote it in the title, and I didn't pay much attention to it... sorry) – noearchimede Jul 19 '17 at 23:42
  • noearchimede, I'm really thank you. You're right. I didn't consider it and have wasted much time trying to solve it. Thanks. – M_K Jul 20 '17 at 15:18
0
if (state = 1)

This is setting state to 1, not testing if it is equal to 1. In other words, it will always be true.

  • Nick Gammom, you're right but this is not that. It was just my typo mistake when I was translating variable's names from my native language to english. In my real code I had "if(state == 1)". But anyway, thank you for your respond. – M_K Jul 20 '17 at 15:23
  • Can you correct your question then? As it is, it is misleading. It is also misleading to post code which is not the problem code in the first place. – Nick Gammon Jul 20 '17 at 21:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.