My code isn't Working

I'm trying to apply an easy buck converter to control a wind turbine, the range of change is from 0-120V,

the arduino uno input is changing from 0-5.66v and I'm trying to apply the mapping function but unfortunately it isn't working properly. before 50V, I want the output to be as the same as the input. after the 50 I want the output to be a precentage from the input. the code is working perfectly in the first part but after it gives some how nonsense output especially in those three number 70,80,90 V

I am using the below code

can anyone plss help to tell me what is my mistake????

the input is A5 and the output is Pin 9

int Vin = analogRead(feedback);

double Vinput = map ( Vin, 0,1023,0,120);
if (Vinput < 50)
{
digitalWrite(PWM,HIGH);
}
if (Vinput > 50)
{
float k = 50/Vinput ;
int pwm = k*255;
pwm = constrain(pwm, 1, 255);
analogWrite(PWM,pwm);
}

currently if this is all of your code, you are constantly updating analogWrite. a more sensible approch would be to updating the pwm only if the Vinput value changes. something like this maybe:

(Compiles, NOT tested!)

#define PWM 9
#define FEEDBACK A5

int previous_Vinput = 0;

void setup() {
  pinMode(9,OUTPUT);
}

void loop() {
  int Vin =  analogRead(FEEDBACK);

  int Vinput = map ( Vin, 0, 1023, 0, 120);
  
  if (Vinput <= 50){
    digitalWrite(PWM, HIGH);
  }
  else if (Vinput != previous_Vinput) //update analogWrite current PWM value only it Vinput is different
  {
    previous_Vinput = Vinput;
    int pwm = (50 * 255)/Vinput;
    pwm = constrain(pwm, 1, 255);
    analogWrite(PWM, pwm);
  }
  
  delayMicroseconds(1000); //optional arbitrary delay to slow things down a bit
}

However I do not think that will give you what you expect either as your 'feedback' is not checked against a 'target value' at the moment.
IMHO you need to implement some form of control loop mechanism where by 'Vin' would be your 'output target value' and 'feedback' your actual output value, then use those 2 value to adjust the 'pwm' as an attempt to maintain the 'output target value'.

hope that helps...

You shouldn't apply more than 5,000 V to an analog input. It can get damaged through this.

The code you have posted is not a complete sketch.
post your complete sketch. From the very first line to the very last line
and do it this way
You should post code by using code-tags
There is an automatic function for doing this in the Arduino-IDE
just three steps

  1. press Ctrl-T for autoformatting your code
  2. do a rightclick with the mouse and choose "copy for forum"
  3. paste clipboard into write-window of a posting

best regards Stefan

Add some serial prints to show you what the values are that you get.

By the way, 5.66V is too high for an Arduino input.

Please post complete code and place code between
** **[code]** **
and
** **[/code]** **
(the so-called code tags).

PS StephanL32 did beat me to it :wink:

sherzaad:
currently if this is all of your code, you are constantly updating analogWrite. a more sensible approch would be to updating the pwm only if the Vinput value changes. something like this maybe:

(Compiles, NOT tested!)

#define PWM 9

#define FEEDBACK A5

int previous_Vinput = 0;

void setup() {
 pinMode(9,OUTPUT);
}

void loop() {
 int Vin =  analogRead(FEEDBACK);

int Vinput = map ( Vin, 0, 1023, 0, 120);
 
 if (Vinput <= 50){
   digitalWrite(PWM, HIGH);
 }
 else if (Vinput != previous_Vinput) //update analogWrite current PWM value only it Vinput is different
 {
   previous_Vinput = Vinput;
   int pwm = (50 * 255)/Vinput;
   pwm = constrain(pwm, 1, 255);
   analogWrite(PWM, pwm);
 }
 
 delayMicroseconds(1000); //optional arbitrary delay to slow things down a bit
}




However I do not think that will give you what you expect either as your 'feedback' is not checked against a 'target value' at the moment.
IMHO you need to implement some form of control loop mechanism where by 'Vin' would be your 'output target value' and 'feedback' your actual output value, then use those 2 value to adjust the 'pwm' as an attempt to maintain the 'output target value'.

hope that helps...

Thanks a lot for your help but the problem still exists, even after applying the code you wrote, as well, what do you mean adding another reference ???
#define TOP 1299 // Fosc = Fclk/(N*(1+TOP), Fosc = 20kHz, Fosc = 16MHz
int pwm=255;
int feedback = A5;
int PWM = 9 ;
void setup() {

pinMode(feedback, INPUT);
pinMode(PWM, OUTPUT);
TCCR1A = 0; //reset the register

TCCR1B = 0; //reset the register

TCNT1 = 0; //reset the register

TCCR1A |= (1<<COM1A1); // set output at non inverting mode

TCCR1A |= (1<<WGM11); // selecting Fast PWM mode

ICR1 = TOP; // setting frequency to 20KHz

TCCR1B |= (1<< CS10)|(1<<WGM12)|(1<<WGM13); //Timer Starts

// delay for compensating the hardware transient time with software

}
void loop() {

int Vin = analogRead(feedback);
float Vinput = map (Vin, 0,1023,0,120);
if (Vinput <= 50)
{
digitalWrite(PWM,HIGH);
}
else if (Vinput > 50)
{
int k = (50)/Vinput;
int pwm = k*255 ;
pwm = constrain(pwm, 1, 1023);
analogWrite(PWM,pwm);
}

}

Why all the useless blank lines, and the lack of indenting (which you can do automatically with the IDE option ctrl-T), and the lack of code tags around your code in the post? Did you read post #2?

StefanL38:
You shouldn't apply more than 5,000 V to an analog input. It can get damaged through this.

The code you have posted is not a complete sketch.
post your complete sketch. From the very first line to the very last line
and do it this way
You should post code by using code-tags
There is an automatic function for doing this in the Arduino-IDE
just three steps

  1. press Ctrl-T for autoformatting your code
  2. do a rightclick with the mouse and choose "copy for forum"
  3. paste clipboard into write-window of a posting

best regards Stefan

Thanks a lot for your answer, here's the complete code:

#define TOP 1299                       // Fosc = Fclk/(N*(1+TOP), Fosc = 20kHz, Fosc = 16MHz  
int pwm = 255;
int feedback = A5;
int PWM = 9 ;
void setup() {


  pinMode(feedback, INPUT);
  pinMode(PWM, OUTPUT);
  TCCR1A = 0;                                 //reset the register


  TCCR1B = 0;                                 //reset the register


  TCNT1 = 0;                                   //reset the register


  TCCR1A |= (1 << COM1A1);                      // set output at non inverting mode


  TCCR1A |= (1 << WGM11);                      // selecting Fast PWM mode


  ICR1 = TOP;                                   // setting frequency to 20KHz


  TCCR1B |= (1 << CS10) | (1 << WGM12) | (1 << WGM13); //Timer Starts


  // delay for compensating the hardware transient time with software


}
void loop() {










  int Vin =  analogRead(feedback);
  float Vinput = map (Vin, 0, 1023, 0, 120);
  if (Vinput <= 50)
  {
    digitalWrite(PWM, HIGH);
  }
  else if (Vinput > 50)
  {
    int k = (50) / Vinput;
    int pwm = k * 255 ;
    pwm = constrain(pwm, 1, 1023);
    analogWrite(PWM, pwm);

@OP

1. You have configured TC1 to generate 20 kHz PWM signal at Dpin-9 and now your job is to modulate/vary the duty cycle of that PWM signal based on some feedback/error signal.

2. Instead of doing the job of Step-1, you are issuing analogWrite(9, arg) command to generate 490 Hz PWM signal at DPin-9 (Fig-1). Why?
pwm328.png
Figure-1:

pwm328.png

Thanks a lot for your answer, here's the complete code:

Clearly not.

abdalla9812:
Thanks a lot for your help but the problem still exists, even after applying the code you wrote,....

told you it wouldn't! :wink:

.... as well, what do you mean adding another reference ???

I mean implementing something like this:

hope that helps...

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.