Do not count THE HALL SENSORE OR DISPLAY THE RESULT. 3 phase BLDC controller

HELLO ALL.

I tried to integrate in a 3 phase PWM a Hall effect sensor counter, and display the solution. it just Dos not worked out.

I’m not even thinking about integrating a DAN algorithm, When i integrated a display and counter it just stopped working.

Please assist.

 / // Sensorless brushless DC (BLDC) motor control with Arduino UNO (Arduino DIY ESC).
// This is a free software without any warranty.
#include <Wire.h> 
#include <LiquidCrystal_I2C.h>

#define SPEED_UP          A0
#define SPEED_DOWN        A1
#define PWM_MAX_DUTY      255
#define PWM_MIN_DUTY      50
#define PWM_START_DUTY    100
byte bldc_step = 0, motor_speed;
unsigned int i;//loop
unsigned int e;//ISR

int hallsensor=2; //hall sensor pin2
volatile long counter;
unsigned long rpm;
unsigned long pass_T;
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);  // Set the LCD I2C address, if it's not working try 0x27.

void setup()
{
    lcd.begin (16,2);
    lcd.home();
    lcd.print("The speed Is,");
//    delay(1000);
//    Serial.begin(9600); //Initiate serial communikation
    attachInterrupt(0,isr2,RISING); //innterupt are called on Rise of input
    pinMode(hallsensor, INPUT); //sets hallsensor as input
    counter=0;
    rpm=0;
    pass_T=0; //initialise values

  DDRD  |= 0x38;           // Configure pins 3, 4 and 5 as outputs
  PORTD  = 0x00;
  DDRB  |= 0x0E;           // Configure pins 9, 10 and 11 as outputs
  PORTB  = 0x31;
  // Timer1 module setting: set clock source to clkI/O / 1 (no prescaling)
  TCCR1A = 0;
  TCCR1B = 0x01;
  // Timer2 module setting: set clock source to clkI/O / 1 (no prescaling)
  TCCR2A = 0;
  TCCR2B = 0x01;
  // Analog comparator setting
  ACSR   = 0x10;           // Disable and clear (flag bit) analog comparator interrupt
  pinMode(SPEED_UP,   INPUT_PULLUP);
  pinMode(SPEED_DOWN, INPUT_PULLUP);
}
// Analog comparator ISR
ISR (ANALOG_COMP_vect) {
  // BEMF debounce
  for(e = 0; e < 10; e++) {
    if(bldc_step & 1){
      if(!(ACSR & 0x20)) e -= 1;
    }
    else {
      if((ACSR & 0x20))  e -= 1;
    }
  }
  bldc_move();
  bldc_step++;
  bldc_step %= 6;
}
void bldc_move(){        // BLDC motor commutation function
  switch(bldc_step){
  case 0:
    AH_BL();
    BEMF_C_RISING();
    break;
  case 1:
    AH_CL();
    BEMF_B_FALLING();
    break;
  case 2:
    BH_CL();
    BEMF_A_RISING();
    break;
  case 3:
    BH_AL();
    BEMF_C_FALLING();
    break;
  case 4:
    CH_AL();
    BEMF_B_RISING();
    break;
  case 5:
    CH_BL();
    BEMF_A_FALLING();
    break;
  }
}
void loop()
{
  PrintRPM();  //void printrpm
  SET_PWM_DUTY(PWM_START_DUTY);    // Setup starting PWM with duty cycle = PWM_START_DUTY
  i = 5000;
  // Motor start
  while(i > 30) {
    delayMicroseconds(i);
    bldc_move();
    bldc_step++;
    bldc_step %= 6;
    i = i - 20;
  }
  motor_speed = PWM_START_DUTY;
  ACSR |= 0x08;                    // Enable analog comparator interrupt
  while(1) {
    while(!(digitalRead(SPEED_UP)) && motor_speed < PWM_MAX_DUTY){
      motor_speed++;
      SET_PWM_DUTY(motor_speed);
      delay(100);
    }
    while(!(digitalRead(SPEED_DOWN)) && motor_speed > PWM_MIN_DUTY){
      motor_speed--;
      SET_PWM_DUTY(motor_speed);
      delay(100);
    }
  }
}
void BEMF_A_RISING(){
  ADCSRB = (0 << ACME);    // Select AIN1 as comparator negative input
  ACSR |= 0x03;            // Set interrupt on rising edge
}
void BEMF_A_FALLING(){
  ADCSRB = (0 << ACME);    // Select AIN1 as comparator negative input
  ACSR &= ~0x01;           // Set interrupt on falling edge
}
void BEMF_B_RISING(){
  ADCSRA = (0 << ADEN);   // Disable the ADC module
  ADCSRB = (1 << ACME);
  ADMUX = 2;              // Select analog channel 2 as comparator negative input
  ACSR |= 0x03;
}
void BEMF_B_FALLING(){
  ADCSRA = (0 << ADEN);   // Disable the ADC module
  ADCSRB = (1 << ACME);
  ADMUX = 2;              // Select analog channel 2 as comparator negative input
  ACSR &= ~0x01;
}
void BEMF_C_RISING(){
  ADCSRA = (0 << ADEN);   // Disable the ADC module
  ADCSRB = (1 << ACME);
  ADMUX = 3;              // Select analog channel 3 as comparator negative input
  ACSR |= 0x03;
}
void BEMF_C_FALLING(){
  ADCSRA = (0 << ADEN);   // Disable the ADC module
  ADCSRB = (1 << ACME);
  ADMUX = 3;              // Select analog channel 3 as comparator negative input
  ACSR &= ~0x01;
}
void AH_BL(){
  PORTB  =  0x04;
  PORTD &= ~0x18;
  PORTD |=  0x20;
  TCCR1A =  0;            // Turn pin 11 (OC2A) PWM ON (pin 9 & pin 10 OFF)
  TCCR2A =  0x81;         //
}
void AH_CL(){
  PORTB  =  0x02;
  PORTD &= ~0x18;
  PORTD |=  0x20;
  TCCR1A =  0;            // Turn pin 11 (OC2A) PWM ON (pin 9 & pin 10 OFF)
  TCCR2A =  0x81;         //
}
void BH_CL(){
  PORTB  =  0x02;
  PORTD &= ~0x28;
  PORTD |=  0x10;
  TCCR2A =  0;            // Turn pin 10 (OC1B) PWM ON (pin 9 & pin 11 OFF)
  TCCR1A =  0x21;         //
}
void BH_AL(){
  PORTB  =  0x08;
  PORTD &= ~0x28;
  PORTD |=  0x10;
  TCCR2A =  0;            // Turn pin 10 (OC1B) PWM ON (pin 9 & pin 11 OFF)
  TCCR1A =  0x21;         //
}
void CH_AL(){
  PORTB  =  0x08;
  PORTD &= ~0x30;
  PORTD |=  0x08;
  TCCR2A =  0;            // Turn pin 9 (OC1A) PWM ON (pin 10 & pin 11 OFF)
  TCCR1A =  0x81;         //
}
void CH_BL(){
  PORTB  =  0x04;
  PORTD &= ~0x30;
  PORTD |=  0x08;
  TCCR2A =  0;            // Turn pin 9 (OC1A) PWM ON (pin 10 & pin 11 OFF)
  TCCR1A =  0x81;         //
}

void SET_PWM_DUTY(byte duty){
  if(duty < PWM_MIN_DUTY)
    duty  = PWM_MIN_DUTY;
  if(duty > PWM_MAX_DUTY)
    duty  = PWM_MAX_DUTY;
  OCR1A  = duty;                   // Set pin 9  PWM duty cycle
  OCR1B  = duty;                   // Set pin 10 PWM duty cycle
  OCR2A  = duty;                   // Set pin 11 PWM duty cycle
}
void PrintRPM()
  {
    delay(1999); //update rpm every 2 second, i is reserved for the calculation
    detachInterrupt(0); //interrupt are disabled
    rpm=(60000*(counter/24))/(millis()-pass_T);
    pass_T=millis();
    counter=0;
    lcd.begin (0,1);
    lcd.print("RPM=");
    lcd.print(rpm); //print out result on monitor
    attachInterrupt(0,isr2,RISING); //Restart the interrupt processing
  }
void isr2()
     //Each rotation, this interrupt function is run twice,
     // into consideration for calculating RPM
  {
     //update counter
    counter++;
  }

When i integrated a display and counter it just st0ped working

What a load of rubbish. The code did not stop working. It stopped compiling, so it is pointless to talk about it working, or not.

fanspec fanspace[3]={1,24}; char fan = 1; ///{0,1},{1,2},{2,8}

ONE statement per line. Do NOT EVER mix declaring variables of different types on one line.

interrupts();    // Enables interrupts
delay (1000);  
noInterrupts();  // Disable interrupts

You might as well quit now. This is the worst possible way to measure interrupts per second.

Speed = ((ticks * 60)/fanspace[fan].fandiv);

Why are you using a char as the index into the fanspace array? Use a reasonable type, like byte.

Please correct your post above and add code tags around your code:

[code]

[color=blue]// your code is here[/color]

[/code]

.

It should look like this:

// your code is here

(Also press ctrl-T (PC) or cmd-T (Mac) in the IDE before copying to indent your code properly)


the warning message you see is because you declared

char fan = 1;

and then use this as an index in an array. a char can be negative, so the compiler warns you of a possible risk there.

you also have fan initialized at 1 and access

fanspace[fan].fandiv

fanspace has proper space reserved as you declared it as an array of 3 entries

fanspec fanspace[3] = {1, 24};

but you only initialized the entry at index 0 (and in a very weird way), not 1...

This line of code

char  SpeedString[4];    // Buffer to store string of 4 chars + 0 termination

does not give you space for 4 chars PLUS the trailing '\0' --> you might overflow

I chaneg the code. no compillations erro found… still not working

you use the global variable i in the loop and in the ISR... that's probably a very bad idea

please fix your post with the code... add code tags

still not working

The code absolutely IS working. If it is not going what you expect, it is your expectation that are wrong.

You need to explain what the program ACTUALLY does, and how that differs from what you expect, so we can help you understand why your expectations are wrong.

int fan = 1; ///{0,1},{1,2},{2,8}

Get rid of the stupid comments.

//40

WTF is that supposed to mean?

  attachInterrupt(12, pickrpm, RISING);

Which Arduino are you using that has 13 or more external interrupts?

  ticks = 0;      // Make ticks zero before starting interrupts.

Interrupts are already enabled.

  //Times sensorclicks (which is apprioxiamately the frequency the fan
  //is spinning at) by 60 seconds before dividing by the fan's divider
  Speed = (((ticks * 60)/24)/fanspace[fan].fandiv);

You have NO idea how much time has elapsed, so you are NOT calculating a speed.

  char  SpeedString[4];    // Buffer to store string of 4 chars + 0 termination
  sprintf(SpeedString, "%4d", Speed);

You can NOT write 4 characters AND A TERMINATING NULL in a 4 element array. Get over it.

You REALLY need to learn what the volatile keyword means, and when to use it.

THANK YOU WEARY MACH FOR THE HELP! i am grateful for the effort.

I replaced the Hall sensor algorithm, it has given me a headache.
Added 2 void "isr2", and "PrintRPM" witch i given to the "ISR". The isr2 should count the Hall signal, the Print RPM should calculate and print the RPM. I have replaced the "i" variable in loop to "e" variable.
The "//40", "//60" line count previously was for debugging purpose.
I got now the start up massage, and the 0 start up RPM, and then nothing. Hall count, calculation, print in the result in loop, dos not.
Separately they are working just fine..

The new not workable version is in the Main post updated.
Please Assist

The new not workable version is in the Main post updated.
Please Assist

Not going to happen. NEVER replace cod that someone has already commented on.

OP, I'm guessing your first language isn't English...
Maybe worth visiting one of the language specific sections - where someone may be able to collaborate with you.

PaulS. Sorry, I did not know.
I'm making a Garage projekt.
The "old" version was for me a dead end. I did not understud the logic behind the Fan's Array. Yesit could be used as a Mill/ H Km/h counter regarding the weel diameter. So I tried to learn and make it work. And i learn.
I remember some stuff from C++.( That was 15 year ago). Revers ingenearing a few things in the code. And there is still something's is missing from success. The secund Stage gona be, to rewrite the hole thin to a 3 phase inverer algorithm, insted of PMW. Forthr PWM test version, all the electric part are together. In the meantime step by step
Programing site:
-display, (done)
-counter (done)

  • signal generator (Recived from Siple projekt)
  • integrate all to one (work in progress)
  • replikate all on a 3 phase Invertert (found on the net) code
    Building in a PID process and controlling button for RPM..
    I need time till the electric parts for The inverter version gone arrive to me. And some of them is realy hard to get, an still hunting..

lastchancename
Indeed! Born in Hungarian, studied in Poland, Live in Germany.
My Engilsh is not so bad at all.i have seen worst. And my Typonise is quite good to..
You motto reflect 100% you personally. Thanks for the suggestion, will try on different languages to if I not successful here.

Obviously, we understand you, but the detail disappears in the translation!
Happy to keep plugging away.

Details:
I tried to merge the PWM signal generator with the "Hall effect counter" rotation counter. And its freezing. I have no clue whay. I know i made an error in the code, but can't figure out where. Got to the point, where in the first loop the starting rotation.. I mean the 0 RPM is displayed, then nothing happens when i manualy rotate the Rotor. the counter dos not do anything, dos not dispaly or refresh ewery 2 second the actual RPM, witch is workable and displaying the rotation speed as a standalone code. I can think of 3 things.

  • I'm running out of ram,
  • The timing setting and interrupt cousing some touble
  • the counter Function is called once.
    Or i'm realy on a bad track.
    The Motor is a Samsung 3 phase 36 Stator and 24 Rotor Pole motor with built in double Hallsensor.