1

I have been working with Arduino for almost a year, because I found it easy for beginners in electronics. But now, I have a major problem, I'm trying to get rid of my delay() function because I want my Arduino Nano to handle to tasks at once:

1-Read MIDI data and transfert it into a pwm signal, as well as monitoring the on and off of the signal (which are bytes). This part works correctly, but i'm not using the mirco(), i'm using a library called Timer1.

2-Generate a PWM signal of 20% dutycycle with a frequency ranging from 1 to 103 Hz using a potentiometer to adjust the frequency.

So, what happens is that the signal I measure on my oscilloscope is a PWM at 50% duty cycle and with frequencies that don't match my calculations at all. Also, It doesn't change smoothly, the frequency goes from 159Hz to let's say 180Hz only at one particular point on the potentiometer, just like if all the rest of it was useless. I decided to monitor all my values with Serial and everything was good, the values were OK and nothing was wrong. Then I decided to change all my variables to floats so I could maybe get more precision... Didn't work as well. So now I'm kind of desesperate.

//MANUAL MODE TEST WITH MICROS()
//VARIABLES ASSIGNEMENT
unsigned long current=0.0;
unsigned long previous=0.0;

float TimeOn = 0.0;
float TimeOff = 0.0;
float manuelF = 0.0;
float sensor = 0.0;

int pin = 11;

byte state = LOW;

//SETUP AND PIN ASSIGNEMENT
void setup() {
  pinMode(9, OUTPUT);//MUSIC SIGNAL OUTPUT
  pinMode(11, OUTPUT);//MANUAL SIGNAL OUTPUT
  pinMode(A5, INPUT);//POTENTIOMETER MANUAL
  pinMode(A6, INPUT);//POTENTIOMETER MUSIC
  Serial.begin(9600);
}

void loop() {

  sensor = analogRead(A5);
  manuelF=((sensor+10.0)/10.0); //Capture la fréquence sur A5
  TimeOn=1000000.0*(0.2*(1.0/manuelF));
  TimeOff=1000000.0*(0.8*(1.0/manuelF));
  current = micros();

  Serial.println(TimeOn);

  //Serial.print("A5 read:");
  //Serial.println(analogRead(A5),8);
  //Serial.println("-----------");
  //Serial.print("Fréquence: ");
  //Serial.println(manuelF,8);
  //Serial.print("timeon:");
  //Serial.println(TimeOn,8);
  //Serial.print("timeoff:");
  //Serial.println(TimeOff,8);


  if ((state == LOW)&&(current - previous >= TimeOff)){  
      state = HIGH;
      digitalWrite(pin,state);
      previous = current;
    }
  else{
    if (current - previous >= TimeOn){
      state = LOW;
      digitalWrite(pin,state);
      previous =current;
    }

  }   
 }

As you can see I'm still monitoring the TimeOn variable. Well, It shows exactly (to 4 micro seconds precise) the time that it is supposed to be ON.

My output at that moment is a 50% duty cycle with a frequency of 53Hz when I pass the 7k on the potentiometer (it is a 10k). Before that, it doesn't even outputs a signal.

What is going on?

EDIT#1: I have done the modifications that @Edgar Bonet suggested me. It partially worked. What i'm left with now is a PWM that can go from 1Hz to 5Hz almost smoothly with the duty cycle at 20% for 1Hz and going up to 22% at 5Hz. After that I only get very discrete frequencies: 7.99Hz, 9.55Hz, 10.66Hz, 11.99Hz, 13.70Hz, 19.18Hz, 21.32Hz, 26.65Hz, 35.54Hz and then it takes almost half a turn before it changes to 53.3Hz until the end. The duty cycle at 35Hz is 33.3% and it reaches 50% at 53.3Hz... What logic is that....

2 Answers 2

0

You wrote:

if ((state == LOW)&&(current - previous >= TimeOff)){  
    state = HIGH;
    digitalWrite(pin,state);
    previous = current;
  }
else{
  if (current - previous >= TimeOn){
    state = LOW;
    digitalWrite(pin,state);
    previous =current;
  }

While you probably mean:

if (state == LOW && current - previous >= TimeOff) {  
    state = HIGH;
    digitalWrite(pin, state);
    previous = current;
}
else if (state == HIGH && current - previous >= TimeOn) {
    state = LOW;
    digitalWrite(pin, state);
    previous =current;
}
2
  • Thank you! It solved a good part of the problem. Now, I can control a PWM from 1Hz to 5Hz almost smoothly with the duty cycle at 20% for 1Hz and going up to 22% at 5Hz. After that I only get very discrete frequencies: 7.99Hz, 9.55Hz, 10.66Hz, 11.99Hz, 13.70Hz, 19.18Hz, 21.32Hz, 26.65Hz, 35.54Hz and then it takes almost half a turn before it changes to 53.3Hz until the end. The duty cycle at 35Hz is 33.3% and it reaches 50% at 53.3Hz... What logic is that....
    – PyThagoras
    Sep 9, 2017 at 18:14
  • changed current=micros() to current=millis(), gives even worse results...
    – PyThagoras
    Sep 10, 2017 at 20:23
0

I have found the problem. Part of it was the code, thank you @Edgar Bonet. The other part was the pin I was using to generate the PWM signal. Throughout my reasearch, I found that on the arduino nano, the timer pins are the same than those on the arduino Uno. Thus:

Timer0 :pins 5-6

Timer1 :pins 9-10

Timer2 :pins 3-11

Since I was using the function micros() which uses the timer0, I had to send the signal to the right pin. I cannot describe why it did send a certain PWM to discrete frequencies, but the important is that it now works.

In parallel, because the other part of my program is using timer1, the two data transmission won't interfere with each other!

Time inversted in researches: 4hours

Hope this helps someone! Thanks.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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