Volatile int

Добрый день! Не могли бы подсказать ?

Задача: по соответствующему коду с датчиков холла на bldc хочу зайти в соответствующую подпрограмму прерывания и подавать из нее PWM на пины.

У примеру, если появился сигнал (RISING) на hallB, должен зайти в void hall_CB () и подать напряжение на 9 и 10.
На 13-м у меня прикручен LED, чтобы понимать, что выполняется именно подпрограмма void hall_CB ()

Загрузил программу, вращаю вручную моторчик. LED на pin13 не загорается вообще, либо горит постоянно. То есть программа зависает в одной из подпрограмм прерывания.


int hallA = LOW; int hallB = LOW; int hallC = LOW; 
volatile int PWM = 0;  // PWM signal will be appears while some interruptions due to hall commands

void setup() {
 Serial.begin(9600);
pinMode(3, OUTPUT);pinMode(5, OUTPUT); pinMode(6, OUTPUT);pinMode(9, OUTPUT); pinMode(10, OUTPUT);pinMode(11, OUTPUT); 
digitalWrite(3, LOW); digitalWrite(5, LOW);digitalWrite(6, LOW);digitalWrite(9, LOW); digitalWrite(10, LOW);digitalWrite(11, LOW);

// Arduino reads hall sensors of the BLDC motor (interraption for Leonardo)
pinMode(0, INPUT_PULLUP); //  hallA - pin D0 - int 2 
pinMode(1, INPUT_PULLUP); //  hallB - pin D1 - int 3
pinMode(2, INPUT_PULLUP); // hallC- pin D2 - int  1
     
attachInterrupt(3, hall_CB, RISING); //  hall_B RISING, Code(halls ACB) = 011,  D1 - int3
attachInterrupt(1, hall__B, FALLING);  // hall_C FALLING, Code = 001,  D2 - int1
attachInterrupt(2, hallA_B, RISING);  // hall_A RISING, Code = 101,  D0 - int2
attachInterrupt(3, hallA__, FALLING);  // hall_B FALLING, Code = 100,  D1 - int3  (3  5)
attachInterrupt(1, hallAC_, RISING);  //  hall_C RISING, Code = 110,  D2 - int1
attachInterrupt(2, hall_C_, FALLING);  // hall_A FALLING, Code = 010,  D0 - int2
    
}


void loop() {
 digitalWrite(3, LOW); digitalWrite(5, LOW);digitalWrite(6, LOW);digitalWrite(9, LOW); digitalWrite(10, LOW);digitalWrite(11, LOW);
PWM = (analogRead(A0));// read the potentiometer that adjust PWM 
PWM = map (PWM, 0, 1023, 0, 255);

 hallA = digitalRead(0); // желтый
 hallB = digitalRead(1);  // зеленый
 hallC = digitalRead(2); // синий

//Serial.print("hallA="); Serial.print(hallA); Serial.print(" ");
 // Serial.print("hallC="); Serial.print(hallB); Serial.print(" ");
 //Serial.print("hallB="); Serial.print(hallC);Serial.println(" ");


}

// A-, B+ 
void hall_CB () {
analogWrite(9, PWM); // (A-)=pin9, transistor М4 
analogWrite(10, PWM); // (B+)=pin10, transistor М5
digitalWrite(13, HIGH); // checking
Serial.println("hallB ???");
}

// B+, C- 
void hall__B () {
analogWrite(10, PWM); // (B+)=pin10, transistor М5
analogWrite(11, PWM); // (C-)=pin11, transistor М6  
}

// A+, C-
void hallA_B () {
analogWrite(3, PWM); // (A+)=pin3, transistor М1
analogWrite(11, PWM); // (C-)=pin11, transistor М6
} 

 // A+, B- 
void hallA__ () {
 analogWrite(3, PWM); // (A+)=pin3, transistor М1
analogWrite(5, PWM); // (B-)=pin5, transistor М2  
  }

  // C+, B-
void hallAC_ (){
analogWrite(6, PWM); // (C+)=pin6, transistor М3
analogWrite(5, PWM); // (B-)=pin5, transistor М2  
}

  // A-, C+
void hall_C_ (){
 analogWrite(9, PWM); // (A-)=pin9, transistor М4
 analogWrite(6, PWM); // (C+)= pin6, transistor М3
}


 

Какой эффект ожидается от такого комбо?

@Лнд
На один пин нельзя присвоить более одного прерывания за раз.
Но вы можете переприсваивать прерывания на ходу. Например. словили RISING -и прямо в прерывании присвоили обработчик на Falling. Потом наоборот.

И да, когда выкладываете код на форум - не пишите по многу операторов на одной строке:

это очень затрудняет чтение.

Это вообще плохой стиль оформления.

Извините, таким образом?

// A-, B+ 
void hall_CB () {
analogWrite(9, PWM); // (A-)=pin9, transistor М4 
analogWrite(10, PWM); // (B+)=pin10, transistor М5

attachInterrupt(3, hall_CB, FALLING);     

digitalWrite(13, HIGH); // checking
Serial.println("hallB ???");
}

Да, attachInterrupt прямо в прерывании. Только лучше это делать последней строкой.

А вот то что вы в прерывании вызываете Сериал - показывает, что учебник вы не читали. Это прямой путь к зависанию программы, что у вас и происходит.

Ну и как бы пины входа 0,1,2
А прерывания INT0/INT1 (ну ещё какой то непонятный INT3), оно так не работает

не хочет загораться((


int hallA = LOW; 
int hallB = LOW; 
int hallC = LOW; 
volatile int PWM = 0;  // PWM signal will be appears while some interruptions due to hall commands

void setup() {
 Serial.begin(9600);
pinMode(3, OUTPUT);
pinMode(5, OUTPUT); 
pinMode(6, OUTPUT);
pinMode(9, OUTPUT); 
pinMode(10, OUTPUT);
pinMode(11, OUTPUT); 
digitalWrite(3, LOW);
 digitalWrite(5, LOW);
 digitalWrite(6, LOW);
 digitalWrite(9, LOW); 
 digitalWrite(10, LOW);
 digitalWrite(11, LOW);

// Arduino reads hall sensors of the BLDC motor (interraption for Leonardo)
pinMode(0, INPUT_PULLUP); //  hallA - pin D0 - int 2 
pinMode(1, INPUT_PULLUP); //  hallB - pin D1 - int 3
pinMode(2, INPUT_PULLUP); // hallC- pin D2 - int  1
     
attachInterrupt(3, hall_CB, RISING); //  hall_B RISING, Code(halls ACB) = 011,  D1 - int3
attachInterrupt(1, hall__B, FALLING);  // hall_C FALLING, Code = 001,  D2 - int1
attachInterrupt(2, hallA_B, RISING);  // hall_A RISING, Code = 101,  D0 - int2
attachInterrupt(3, hallA__, FALLING);  // hall_B FALLING, Code = 100,  D1 - int3  (3  5)
attachInterrupt(1, hallAC_, RISING);  //  hall_C RISING, Code = 110,  D2 - int1
attachInterrupt(2, hall_C_, FALLING);  // hall_A FALLING, Code = 010,  D0 - int2 

digitalWrite(13, LOW); // checking
}

void loop() {
digitalWrite(3, LOW);
digitalWrite(5, LOW);
digitalWrite(6, LOW);
digitalWrite(9, LOW); 
digitalWrite(10, LOW);
digitalWrite(11, LOW);
PWM = (analogRead(A0));// read the potentiometer that adjust PWM 
PWM = map (PWM, 0, 1023, 0, 255);

 hallA = digitalRead(0); // yellow
 hallB = digitalRead(1);  // green
 hallC = digitalRead(2); // blue
}

// A-, B+ 
void hall_CB () {
analogWrite(9, PWM); // (A-)=pin9, transistor М4 
analogWrite(10, PWM); // (B+)=pin10, transistor М5
attachInterrupt(3, hall_CB, FALLING);
digitalWrite(13, HIGH); // checking
}

// B+, C- 
void hall__B () {
analogWrite(10, PWM); // (B+)=pin10, transistor М5
analogWrite(11, PWM); // (C-)=pin11, transistor М6 
attachInterrupt(1, hall__B, RISING);
}

// A+, C-
void hallA_B () {
analogWrite(3, PWM); // (A+)=pin3, transistor М1
analogWrite(11, PWM); // (C-)=pin11, transistor М6
attachInterrupt(2, hallA_B, FALLING);
} 

 // A+, B- 
void hallA__ () {
 analogWrite(3, PWM); // (A+)=pin3, transistor М1
analogWrite(5, PWM); // (B-)=pin5, transistor М2 
attachInterrupt(3, hallA__, RISING);
}

  // C+, B-
void hallAC_ (){
analogWrite(6, PWM); // (C+)=pin6, transistor М3
analogWrite(5, PWM); // (B-)=pin5, transistor М2 
attachInterrupt(1, hallAC_, FALLING); 
}

  // A-, C+
void hall_C_ (){
 analogWrite(9, PWM); // (A-)=pin9, transistor М4
 analogWrite(6, PWM); // (C+)= pin6, transistor М3
 attachInterrupt(2, hall_C_, RISING);
}


Почему? Я брал в соответствии


с Леонардо:

а почему опять куча прерываний?

вы похоже нифига не поняли.
Зачем вы назначаете в прерывании снова это же прерывание??? У вас должно быть два разных прерывания на каждый сенсор - одно на райзинг, другое на фэйлинг. И вы из первого назначаете второе и наоборот.

А вы какую-то бессмыслицу написали.

А где именно было указано , что это Леонардо.
Разумом скуден стал видимо

@Лнд
не надо кросс-постить на два форума. Спрашивайте на каком-то одном. Или хотя бы не постите ответы отсюда туда - вы на том форуме выглядите неадекватно из-за этого.

В Wiring есть хороший макрос: pinToInterrupt(uint8_t pin)

более того, только он и рекомендован в документации. Использование номеров прерываний - плохой стиль.