Why doesnt this code work?

Hi
so i was working on this arduino based boost converter, and i wrote this code.

//Voltage Divider on input,Vcc-2100 ohm--970 ohm--gnd , measured the resistance with multimeter. actually 2k-1k resistor
//3V=193:    12V=777: 4.3V=278:  10V=647:  13V=839
//the boost conv has 2140-980 resistors.
//Duty Cycle = 1 - (Vin/Vout)
//pwm value = DutyCycle% x 255
//minimum input = 3V,maximum input = 4.2V fixed output 12V, Minimum duty cycle with no load 65%, max 75%
//*** configured so the boost converter can reach a stable state even in the case of sudden voltage spike
//that might be caused by load discontinution or connection, also while protecting the output from unexpected spikes.

//const int groundControl =  3;    //A low side mosfet switch that controlls all ground to the battery.
//const int voltageReadInput = A2; //Reads input voltage
const int voltageReadOutput = A1;//Reads output Voltage
const int boostConverterPin = 5; //Drives the boost converter.
//const int chargePumpPin = 1;// for around 13V for the mosfet gates.
//int inputVoltage;
int outputVoltage;
int previousVoltage = 0;
byte pwmValue = 165; // (65/100)*255
void setup()
{
// pinMode(groundControl, OUTPUT);
//  pinMode(voltageReadInput, INPUT);
  pinMode(voltageReadOutput, INPUT);
  pinMode(boostConverterPin, OUTPUT);
  Serial.begin(2000000);
//  pinMode(chargePumpPin, OUTPUT);

TCCR0B |= _BV(CS00);
TCCR0B &= ~_BV(CS01);
TCCR0B &= ~_BV(CS02);
TCCR0A |= _BV(WGM00);
TCCR0A |= _BV(WGM01);
TCCR0A &= ~_BV(WGM02);
CLKPR = (1<<CLKPCE);
CLKPR = (0<<CLKPS3) | (0<<CLKPS2) | (0<<CLKPS1) | (0<<CLKPS0);
}

void loop()
{
  analogWrite(boostConverterPin, pwmValue);
  Serial.println(pwmValue);
  if(analogRead(voltageReadOutput) != previousVoltage)// each cycle of the pwm takes a certain amount of time to run. 
  //Say it stays high for 1ms and low for 2ms, So the arduino being able to run multiple loops in that 1ms/2ms, 
  //the pwm value would keep increasing/decreasing. This insures that this loop will surely execute first time,
  //and wait for the voltage to change and then increase/decrease the duty cycle.
  {
  
      if (analogRead(voltageReadOutput) < 770) 
      {                       
        pwmValue++;
      }
      if (analogRead(voltageReadOutput) > 770)
      {
        pwmValue--;
      }
      previousVoltage = analogRead(voltageReadOutput);
//This is a stripped down version for ease of testing.
  }
}

The timer bits are from a forum post i copied, and D5 of arduino nano is on timer0, (i actually intend to shift it to an attiny 13, which only has timer0, so.. timer0)
I ran the code on my nano, and it doesnt do anything, I am sure that my boost converter circuit works fine with analogWrite and actually boosts voltage.

1.When i look at the serial monitor, the value rises from whatever it is, goes to the highest, and then continues to go to the lowest. Previoulsly when i used int to store the value, it went on until it overflowed . why is this happening?
2.This is another code i wrote before

//Voltage Divider on input,Vcc-2100 ohm--970 ohm--gnd , measured the resistance with multimeter. actually 2k-1k resistor
//3V=193:    12V=771: 4.3V=278:  10V=647:  13V=839
//boost conv divider 2140-980




//const int voltageReadInput = A2; //Reads input voltage
const int voltageReadOutput = A1;//Reads output Voltage
const int boostConverterPin = 13; //Drives the boost converter, Also a bjt push-pull, Off when HIGH
int previousVoltage = 0;
int currentVoltage = 0;
unsigned long currentMicros;
unsigned long previousMicros = 0;

bool state = false;
//int inputVoltage;                //so we dont have to read input voltage multiple time per loop.
//int outputVoltage;
int highTime = 65;
int lowTime;  // we are running at 10khz, so each period is T=1/f long, 100 microseconds long, so 65% duty cycle at 4.2V from D= 1-(Vin/Vout)
void setup() {
//  pinMode(groundControl, OUTPUT);
  pinMode(boostConverterPin, OUTPUT);
//  pinMode(voltageReadInput, INPUT);
  pinMode(voltageReadOutput, INPUT);
  Serial.begin(2000000);
}

void loop() {
  lowTime = 100 - highTime;
  currentVoltage = digitalRead(voltageReadOutput);
  if(analogRead(voltageReadOutput < 100))// to check it can pass through 12V without oscillating
  {
    digitalWrite(boostConverterPin, HIGH);
  }
  Serial.println(analogRead(voltageReadOutput));
      currentMicros = micros();
      if (currentMicros - previousMicros >= lowTime && state == false);//has it been off for atleast the low time
      {
        currentMicros = previousMicros;
        digitalWrite(boostConverterPin, LOW);//Turn the pin on
        state = true; //so this loop doesnt get executed when the pin is already on
      }
      if (currentMicros - previousMicros >= highTime && state == true)//has it been on long enough
      {
        currentMicros = previousMicros;
        digitalWrite(boostConverterPin, HIGH);//turn the pin off
        state = false;//same as before.
      }
      //outputVoltage = analogRead(voltageReadOutput);//*****not sure if i should read once, set a variable, then process or read and process everytime. 
     if(previousVoltage != currentVoltage)
     {
      if (analogRead(voltageReadOutput) < 720) //see reference above,771 means 12V Increasing duty cycle increases Voltage
      {
        highTime++;//originally 771= 12V , to give the conv a bit of breathing room.
      }
      if (analogRead(voltageReadOutput) > 820) //same as before, decreasing duty cycle decreases voltage.
      {
        highTime--;
      }
      previousVoltage = currentVoltage;
     }
     Serial.println(highTime);
     
     Serial.println(lowTime);
     
    }

This tried to bitbang pwm and somewhy produced 42.5V constant on the output. When i saw that you can mess with pwm frequency i decided to move from this one.
I feel like im missing understanding of a fundamental process of the loop function.. which is why i cant figure whats wrong.

pwmValue is a byte, which means it can ONLY have values between 0 and 255. You read the output voltage, then blindly increment or decrement pwmValue, without ever checking to see if it has reached its maximum or minimum value. So, it is constantly incrementing up from 0 to 255, than wrapping around to 0 again, and starting over.

Regards,
Ray L.

What? ? ? ?

 if(analogRead(voltageReadOutput < 100))

And oops...

 if (currentMicros - previousMicros >= lowTime && state == false);

RayLivingston:
pwmValue is a byte, which means it can ONLY have values between 0 and 255. You read the output voltage, then blindly increment or decrement pwmValue, without ever checking to see if it has reached its maximum or minimum value. So, it is constantly incrementing up from 0 to 255, than wrapping around to 0 again, and starting over.

Regards,
Ray L.

well, analogWrite does only take value between 0-255..

Im not sure where i am wrong. It should check the voltage every loop.
How i understand this code should work.

1.analogWrite(boostConverterPin, pwmValue); first line of loop, starts outputting the preset value.
2.next one, checks if the voltage is same as before, if it is, the duty cycle didnt change, skip.
3.if the voltage isnt same as before, proceed.
4.IF the voltage reading on the output side is lower than 12V,( voltage divider), increase duty cycle by one.
5.read and set previous voltage in this loop.
6.on the next loop,Read the voltage, If the voltage has changed, the duty cycle increased, but hasnt reached 12V, go do step 4 again.
and the lower portion should do the same thing.
So in my eyes, it should check voltage every loop, it shouldnt blindly increase the pwmValue without checking the voltage, it wouldnt make any sense, the if statement shouldnt blindly activate as it relies on the reading of output Voltage

pcbbc:
What? ? ? ?

 if(analogRead(voltageReadOutput < 100))

And oops...

 if (currentMicros - previousMicros >= lowTime && state == false);

first ones a typo..

The second one though,

am i only missing brackets?

if ((currentMicros - previousMicros) >= lowTime && state == false)

and is there a limit to how many &&s i can put in one statement?
like

if(A<B && (C-D)>A && (B+A-C) != A && bool == true)

kaseftamjid:
first ones a typo..

The second one though,

am i only missing brackets?

if ((currentMicros - previousMicros) >= lowTime && state == false)

and is there a limit to how many &&s i can put in one statement?
like

if(A<B && (C-D)>A && (B+A-C) != A && bool == true)

Second one has an errant semicolon at the end of the “if” statement.
That ; terminates the “if” without doing anything.
The code block in the { } that follows will be executed every time, completely regardless of the state of the “if”.

Edit:
Doesn’t require brackets. You can add them if you think it helps you reading the code. Personally I remember just a few rules....
BODMAS first in the standard order: brackets, orders, division/multiplication, addition/subtraction
Then comparisons: == != > < >= <=
Next Boolean logic operators: && ||

And I save brackets for where they are really needed (otherwise too many levels of brackets make the code unreadable), e.g....
Bit wise logic: & | ^ (otherwise bitwise logic come after comparisons, which you probably don’t want)
When there is both && and || in the same logic expression (Actually && comes before ||, but I doubt very many professional developers can even tell you which without looking up and I expect even those that do would consider it bad coding style not to use brackets to make it clear which you intended)

You should see from the above that neither of your examples require any brackets to be executed in the correct order.

Also, looking again, this is wrong...

 currentMicros = previousMicros;

currentMicros is set at the start of loop.
previousMicros is set to zero at startup and never modified.
Setting currentMicros to zero will achieve nothing (except mess up the logic of the second “if”).

You need to capture currentMicros to previousMicros, not the other way around.

pcbbc:
Second one has an errant semicolon at the end of the “if” statement.
That ; terminates the “if” without doing anything.
The code block in the { } that follows will be executed every time, completely regardless of the state of the “if”.

Edit:
Doesn’t require brackets. You can add them if you think it helps you reading the code. Personally I remember just a few rules....
BODMAS first in the standard order: brackets, orders, division/multiplication, addition/subtraction
Then comparisons: == != > < >= <=
Next Boolean logic operators: && ||

And I save brackets for where they are really needed (otherwise too many levels of brackets make the code unreadable), e.g....
Bit wise logic: & | ^ (otherwise bitwise logic come after comparisons, which you probably don’t want)
When there is both && and || in the same logic expression (Actually && comes before ||, but I doubt very many professional developers can even tell you which without looking up and I expect even those that do would consider it bad coding style not to use brackets to make it clear which you intended)

You should see from the above that neither of your examples require any brackets to be executed in the correct order.

Thanks.. I swear this is the second time i missed that single piece of ; at the end of for loop... Gotta keep on lookout.

I would actually like to use the 1st code, because it can produce more than 10khz which in turn saves me from the pain of inductor hum.
Whats wrong with the first code? It should be simple enough, but even then its not working.. weird.

Why do you keep using multiple analogReads?

TheMemberFormerlyKnownAsAWOL:
Why do you keep using multiple analogReads?

I havent actually figured which one is better. But i guess ill set a variable and then process from it.

I still have no clue why this is acting weird

//Voltage Divider on input,Vcc-2100 ohm--970 ohm--gnd , measured the resistance with multimeter. actually 2k-1k resistor
//3V=193:    12V=777: 4.3V=278:  10V=647:  13V=839
//the boost conv has 2140-980 resistors.
//Duty Cycle = 1 - (Vin/Vout)
//pwm value = DutyCycle% x 255
//minimum input = 3V,maximum input = 4.2V fixed output 12V, Minimum duty cycle with no load 65%, max 75%
//*** configured so the boost converter can reach a stable state even in the case of sudden voltage spike
//that might be caused by load discontinution or connection, also while protecting the output from unexpected spikes.

//const int groundControl =  3;    //A low side mosfet switch that controlls all ground to the battery.
//const int voltageReadInput = A2; //Reads input voltage
const int voltageReadOutput = A1;//Reads output Voltage
const int boostConverterPin = 5; //Drives the boost converter.
//const int chargePumpPin = 1;// for around 13V for the mosfet gates.
//int inputVoltage;
int outputVoltage;
int previousVoltage = 0;
byte pwmValue = 165; // (65/100)*255
void setup()
{
// pinMode(groundControl, OUTPUT);
//  pinMode(voltageReadInput, INPUT);
  pinMode(voltageReadOutput, INPUT);
  pinMode(boostConverterPin, OUTPUT);
  Serial.begin(2000000);
//  pinMode(chargePumpPin, OUTPUT);

TCCR0B |= _BV(CS00);
TCCR0B &= ~_BV(CS01);
TCCR0B &= ~_BV(CS02);
TCCR0A |= _BV(WGM00);
TCCR0A |= _BV(WGM01);
TCCR0A &= ~_BV(WGM02);
CLKPR = (1<<CLKPCE);
CLKPR = (0<<CLKPS3) | (0<<CLKPS2) | (0<<CLKPS1) | (0<<CLKPS0);
}

void loop()
{
  analogWrite(boostConverterPin, pwmValue);
  Serial.println(pwmValue);
  if(analogRead(voltageReadOutput) != previousVoltage)// each cycle of the pwm takes a certain amount of time to run.
  //Say it stays high for 1ms and low for 2ms, So the arduino being able to run multiple loops in that 1ms/2ms,
  //the pwm value would keep increasing/decreasing. This insures that this loop will surely execute first time,
  //and wait for the voltage to change and then increase/decrease the duty cycle.
  {
 
      if (analogRead(voltageReadOutput) < 770)
      {                       
        pwmValue++;
      }
      if (analogRead(voltageReadOutput) > 770)
      {
        pwmValue--;
      }
      previousVoltage = analogRead(voltageReadOutput);
//This is a stripped down version for ease of testing.
  }
}

...

kaseftamjid:
I havent actually figured which one is better. But i guess ill set a variable and then process from it.

Reading ONCE and then processing is far better. As it’s an analogue read you have no guarantee a second read will be the same as the first, even if the system is in steady state.

You said you’d set a variable, but your latest code doesn’t do that.

You say “acting weird” but you don’t provide any test data to show what “weird” is, or say what you expected to see, or what you actually observed.

I doubt very much this actually works according to your comments...

 if(analogRead(voltageReadOutput) != previousVoltage)

Analogue reads will have a certain amount of noise, so as I said, even in steady state, very unlikely successive reads will have the same value. Plus of course your repeating the read, not using the previous value.

pcbbc:
Reading ONCE and then processing is far better. As it’s an analogue read you have no guarantee a second read will be the same as the first, even if the system is in steady state.

You said you’d set a variable, but your latest code doesn’t do that.

You say “acting weird” but you don’t provide any test data to show what “weird” is, or say what you expected to see, or what you actually observed.

I doubt very much this actually works according to your comments...

 if(analogRead(voltageReadOutput) != previousVoltage)

Analogue reads will have a certain amount of noise, so as I said, even in steady state, very unlikely successive reads will have the same value. Plus of course your repeating the read, not using the previous value.

The code now

//Voltage Divider on input,Vcc-2100 ohm--970 ohm--gnd , measured the resistance with multimeter. actually 2k-1k resistor
//3V=193:    12V=777: 4.3V=278:  10V=647:  13V=839
//the boost conv has 2140-980 resistors.
//Duty Cycle = 1 - (Vin/Vout)
//pwm value = DutyCycle% x 255
//minimum input = 3V,maximum input = 4.2V fixed output 12V, Minimum duty cycle with no load 65%, max 75%
//*** configured so the boost converter can reach a stable state even in the case of sudden voltage spike
//that might be caused by load discontinution or connection, also while protecting the output from unexpected spikes.

//const int groundControl =  3;    //A low side mosfet switch that controlls all ground to the battery.
//const int voltageReadInput = A2; //Reads input voltage
const int voltageReadOutput = A1;//Reads output Voltage
const int boostConverterPin = 5; //Drives the boost converter.
//const int chargePumpPin = 1;// for around 13V for the mosfet gates.
//int inputVoltage;
int outputVoltage;
int previousVoltage = 0;
byte pwmValue = 0; // (65/100)*255 changed for testing.
void setup()
{
// pinMode(groundControl, OUTPUT);
//  pinMode(voltageReadInput, INPUT);
  pinMode(voltageReadOutput, INPUT);
  pinMode(boostConverterPin, OUTPUT);
  Serial.begin(9600);
//  pinMode(chargePumpPin, OUTPUT);

TCCR0B |= _BV(CS00);
TCCR0B &= ~_BV(CS01);
TCCR0B &= ~_BV(CS02);
TCCR0A |= _BV(WGM00);
TCCR0A |= _BV(WGM01);
TCCR0A &= ~_BV(WGM02);
CLKPR = (1<<CLKPCE);
CLKPR = (0<<CLKPS3) | (0<<CLKPS2) | (0<<CLKPS1) | (0<<CLKPS0);
}

void loop()
{
  analogWrite(boostConverterPin, pwmValue);
  outputVoltage = analogRead(voltageReadOutput);
  Serial.println(pwmValue);
  
  
      if (outputVoltage < 770)//this SHOULD output between 720 to 820 adc val, which means from 11.2V to 12.7V, 
                              //pretty acceptable in my case, plan to set the closest value to 12V. 
      {                       
        pwmValue++;
      }
      if (outputVoltage > 770)
      {
        pwmValue--;
      }
      previousVoltage = outputVoltage;
  
}

serial monitor output attached.

The voltage on the output stays at around 38V. This is all the information i have and am working with. There is no load connected and the mosfet can carry 10Amp at 5V gate.

This is the information i have for now.

Serial monitor.txt (145 KB)