I am trying to build a variable frequency drive
I will measure a current and compare to a reference value
my hall sensor gives 2.5V out for 0 Amps and has a range of 400mV acroos full load
So I write my look up table
int MainRef[] = {
433, 435, 437, 439, 441, 443, 445, 447, 449, 451, 453, 455, 457,
459, 461, 463, 465, 467, 469, 471, 473, 475, 477, 479, 481, 483,
485, 487, 489, 491, 493, 495, 497, 499, 501, 503, 505, 507, 509,
511,
513, 515, 517, 519, 521, 523, 525, 527, 529, 531, 533, 535, 537,
539, 541, 543, 545, 547, 549, 551, 553, 555, 557, 559, 561, 563,
565, 567, 569, 571, 573, 575, 577, 579, 581, 583, 585, 587, 589,
591, 593
}
Now I need to cycle through the table at dead set intervals which needs to be accurate in order to synthesise the sin wave (I know its a staircase!!!)
So I will use a timed interrupt and to calculate the time between table increments I will measure an input voltage between 2.5 and 5 Volts with that relating to 25 Hz-50Hz
Heres the snippet of code to calculate the step time, as the frequency increases then the amplitude of the sin needs to decrease also so less points in the table will be used i.e all 80 values for 50Hz but only 40 Values for 25 Hz this is what NUM is the number of values in the table
float SETUP_VIN =analogRead(A0);
TEST_VIN = SETUP_VIN;
float TEST_HERTZ = ((SETUP_VIN)/1023.0)*50.0;
float FLOAT_NUM = TEST_HERTZ*1.6;
NUM=ceil(FLOAT_NUM);
HERTZ =ceil(TEST_HERTZ);
STEP_TIME = (1000000)/(HERTZ*2*NUM);
So I have the step time calculated
I now add the step time to the timer so that I interrupt every step time to increment the table in a timed manner I start the table at index 40 (dead in the middle) and count up by NUM/2 and down the same
index = 40;
increment=1;
Timer1.initialize();
Timer1.disablePwm(9);
Timer1.disablePwm(10);
Timer1.attachInterrupt(flash);
Timer1.setPeriod(STEP_TIME);
Heres the interrupt program
void flash ()
{
if (index<=40 + (NUM/2)){
(increment=1);
}
else{
if (index>=(40 - (NUM/2))){
increment=-1;}
}
index = index+increment;
Iin=analogRead(A1);
ERR = MainRef[index]-Iin;
if (ERR>= 2){
digitalWrite(GATE, HIGH);}
else{
if (ERR <= -2){
digitalWrite(GATE, LOW);}
}
}
Every time the period STEP_TIME passes the program jumps to flash where it increments or decrements the table and cycles through it measures the current and makes a decision on which transistor gate to turn on
Now this program so far works, I see with my scope that the interrupt does indeed work and the table does increment as I want it to
But.........................
I want to check the input voltage to see if any speed change has been commanded and this is where I am really stuck
What I want is to recheck the input voltage and see if its changed since it as setup, if theres a change then I need to stop the interrupt and recalculate the step time and then reload the timer with the new value
This is what I have done
void loop(){
Vin=analogRead(A0);
int x = abs(TEST_VIN - Vin);
if (x>7){
Vin=analogRead(A0);
x = (TEST_VIN - Vin);
if(x>10, x<-10){
digitalWrite(13, HIGH);
noInterrupts();
volatile int SETUP_VIN2 =analogRead(A0);
TEST_VIN = SETUP_VIN2;
Vin=analogRead(A0);
float TEST_HERTZ2 = ((SETUP_VIN2)/1023.0)*50.0;
float FLOAT_NUM2 = TEST_HERTZ2*1.6;
NUM2=ceil(FLOAT_NUM2);
HERTZ2 =ceil(TEST_HERTZ2);
STEP_TIME2 = (1000000)/(HERTZ2*2*NUM2);
Serial.print("NEWSTEP_TIME ");
Serial.println(STEP_TIME2);
Serial.print("TEST_VIN ");
Serial.println(TEST_VIN);
index = 43;
increment=1;
delay(5000);
Timer1.setPeriod(STEP_TIME2);
interrupts();
digitalWrite(13, LOW);
}
}
}
Vin is re-read
TEST_VIN-Vin is calculated and x = abs(TEST_VIN - Vin) is used to see how much the value has changed
Because of some dodgy readings I have done a double if to try to (unsuccesfully) stop strange readings
if the voltage has changed by more than 10 codes I want to re setup the step time but I want to stop the interrupt why it does this hence me trying to delay it and writing pin 13 high so I can see it on my scope
But it just does not work right I think it may well have something to do with me reusing values all over the place I just dont know what to do to move this forward I have been on 3 days trying
Here is my entire program
#include <TimerOne.h>
volatile int TEST_VIN;
volatile int TEST_VIN2;
float TEST_HERTZ;
float FLOAT_NUM;
float TEST_HERTZ2;
float FLOAT_NUM2;
volatile int NUM;
volatile int HERTZ;
volatile int STEP_TIME;
volatile int NUM2;
volatile int HERTZ2;
volatile int STEP_TIME2;
volatile int Vin;
volatile int x;
int MainRef[] = {
433, 435, 437, 439, 441, 443, 445, 447, 449, 451, 453, 455, 457,
459, 461, 463, 465, 467, 469, 471, 473, 475, 477, 479, 481, 483,
485, 487, 489, 491, 493, 495, 497, 499, 501, 503, 505, 507, 509,
511,
513, 515, 517, 519, 521, 523, 525, 527, 529, 531, 533, 535, 537,
539, 541, 543, 545, 547, 549, 551, 553, 555, 557, 559, 561, 563,
565, 567, 569, 571, 573, 575, 577, 579, 581, 583, 585, 587, 589,
591, 593
};
volatile int index;
volatile int increment ;
long unsigned int REF = MainRef[index];
int Iin;
int ERR;
int GATE = 12;
int SPEED_CHANGE;
void setup()
{
Serial.begin(9600);
pinMode(13, OUTPUT);
pinMode(GATE, OUTPUT);
pinMode(8, OUTPUT);
pinMode(7, INPUT);
bitClear(ADCSRA,ADPS0) ;
bitClear(ADCSRA,ADPS1) ;
bitSet(ADCSRA,ADPS2) ;
index = 40;
float SETUP_VIN =analogRead(A0);
TEST_VIN = SETUP_VIN;
float TEST_HERTZ = ((SETUP_VIN)/1023.0)*50.0;
float FLOAT_NUM = TEST_HERTZ*1.6;
NUM=ceil(FLOAT_NUM);
HERTZ =ceil(TEST_HERTZ);
STEP_TIME = (1000000)/(HERTZ*2*NUM);
Serial.println(STEP_TIME);
Serial.print("HERTZ ");
Serial.println(HERTZ);
Serial.print("NUM ");
Serial.println(NUM);
Timer1.initialize();
Timer1.disablePwm(9);
Timer1.disablePwm(10);
Timer1.attachInterrupt(flash);
Timer1.setPeriod(STEP_TIME);
increment=1;
}
void flash ()
{ digitalWrite(8, HIGH);
if (index<=40 + (NUM/2)){
(increment=1);
}
else{
if (index>=(40 - (NUM/2))){
increment=-1;}
}
index = index+increment;
Iin=analogRead(A1);
ERR = MainRef[index]-Iin;
if (ERR>= 2){
digitalWrite(GATE, HIGH);}
else{
if (ERR <= -2){
digitalWrite(GATE, LOW);}
}
digitalWrite(8, LOW);
}
void loop(){
Vin=analogRead(A0);
int x = abs(TEST_VIN - Vin);
if (x>7){
Vin=analogRead(A0);
x = (TEST_VIN - Vin);
if(x>10, x<-10){
digitalWrite(13, HIGH);
noInterrupts();
volatile int SETUP_VIN2 =analogRead(A0);
TEST_VIN = SETUP_VIN2;
Vin=analogRead(A0);
float TEST_HERTZ2 = ((SETUP_VIN2)/1023.0)*50.0;
float FLOAT_NUM2 = TEST_HERTZ2*1.6;
NUM2=ceil(FLOAT_NUM2);
HERTZ2 =ceil(TEST_HERTZ2);
STEP_TIME2 = (1000000)/(HERTZ2*2*NUM2);
Serial.print("NEWSTEP_TIME ");
Serial.println(STEP_TIME2);
Serial.print("TEST_VIN ");
Serial.println(TEST_VIN);
index = 43;
increment=1;
delay(5000);
Timer1.setPeriod(STEP_TIME2);
interrupts();
digitalWrite(13, LOW);
}
}
}
The digital writes and serial stuff can all be dropped later its only for me to try and see whats going wrong
Any help much appreciated, can I use the nointerrupt() to stop the timer command or should I detach interrupt? it doesnt seem to work either way so how would an expert here go about resetting up something I did earlier its really confusing how the program doesnt see things from the setup within the loop