Вроде все просто, а ничего не понимаю.
- Войдите на сайт для отправки комментариев
Есть САМОПИСНЫЙ и частично стыренный код. Сижу уже вторые сутки, втыкаю, читаю датащиты и не пойму как это все вообще работает и что он делает.
Есть клавиатура 4х4 и расширитель портов mcp23017 в виде модуля ардуиновского. Всем этим управляет 328p. Мне нужно без задержек реагировать на нажатия клавиш. Был создан бесконечный цикл, в котором крутиться шаговик. Проверять этот порт расширителя mcp очень расточительно, т.к. задержка полуается приличная около 510 мкс. Для этого было решено использовать прерывания. В общем в итоге две кнопки из всей клавиатуры более менее отрабатывают прерывание, остальные тоже, но из прерываний выходить не желают. Там же вроде схема управления простая, а чего не работает не понимаю.
Клавиатура какая-то такая.

#include <Wire.h> #include <Adafruit_MCP23017.h> #include <AccelStepper.h> byte arduinoIntPin = 2; // ... and this interrupt vector byte arduinoInterrupt = 1; volatile boolean awakenByInterrupt = false; volatile boolean awakenByInterruptPin[10]; #define BalanceStepPin 3 #define BalanceDirPin 4 #define RightLegStepPin 5 #define RightLegDirPin 6 #define LeftLegStepPin 7 #define LeftLegDirPin 8 #define RightFootStepPin 9 #define RightFootDirPin 10 #define LeftFootStepPin 11 #define LeftFootDirPin 12 const char Balance = 0; const char RightLeg = 1; const char LeftLeg = 2; const char RightFoot = 3; const char LeftFoot = 4; volatile uint8_t pin; Adafruit_MCP23017 mcp; float oldSpeed = 0; const int Motor_number = 5; const byte ROWS = 4; // const byte COLS = 4; // const char keys[ROWS][COLS] = { {'1', '2', '3', 'A'}, {'4', '5', '6', 'B'}, {'7', '8', '9', 'C'}, {'*', '0', '#', 'D'} }; byte rowPins[ROWS] = {3, 2, 1, 0}; byte colPins[COLS] = {7, 6, 5, 4}; AccelStepper* motorLink[Motor_number]; // bool Rotate(int num, bool rotating, int param, int Speed, int Accel) { Serial.println("InRotate"); awakenByInterruptPin[0] = true; long long Stopor = 6000000; if (rotating) Stopor = -Stopor; motorLink[num]->setMaxSpeed(Speed); motorLink[num]->setAcceleration(Accel); motorLink[num]->moveTo(Stopor); // while (mcp.digitalRead(colPins[param - 1]) == HIGH) Serial.println(String(awakenByInterruptPin[colPins[param - 1]])); Serial.print(String(colPins[param - 1])); Serial.print(String(" = ")); Serial.println(String(pin)); int iteration = 0; attachInterrupt(arduinoInterrupt, intCallBack, RISING); while (awakenByInterruptPin[0/*colPins[param - 1]*/]) { iteration++; motorLink[num]->run(); Serial.print("InWhile"); Serial.println(iteration); // delay(500); if (awakenByInterrupt) { awakenByInterruptPin[0] = false; Serial.println("awaken_from_While"); handleInterrupt(); } if (iteration > 100) awakenByInterruptPin[0] = false; } detachInterrupt(arduinoInterrupt); if (awakenByInterrupt) handleInterrupt(); Serial.println("after_while"); oldSpeed = motorLink[num]->speed(); motorLink[num]->setMaxSpeed(0); while (motorLink[num]->speed() != 0) { motorLink[num]->run(); Serial.println("InNextWhille"); } motorLink[num]->setMaxSpeed(oldSpeed); Serial.println("OutRotate"); return 1; } void setup() { Serial.begin(9600); pinMode(arduinoIntPin, INPUT); Serial.println("inSetup"); mcp.begin(); // use default address 0 mcp.setupInterrupts(false, false, LOW); mcp.pinMode(0, OUTPUT); mcp.pinMode(1, OUTPUT); mcp.pinMode(2, OUTPUT); mcp.pinMode(3, OUTPUT); mcp.pinMode(4, INPUT); mcp.pullUp(4, HIGH); mcp.setupInterruptPin(4, FALLING); mcp.pinMode(5, INPUT); mcp.pullUp(5, HIGH); mcp.setupInterruptPin(5, FALLING); mcp.pinMode(6, INPUT); mcp.pullUp(6, HIGH); mcp.setupInterruptPin(6, FALLING); mcp.pinMode(7, INPUT); mcp.pullUp(7, HIGH); mcp.setupInterruptPin(7, FALLING); Serial.println("ExitSetup"); motorLink[RightLeg] = new AccelStepper(AccelStepper::FULL2WIRE, RightLegDirPin, RightLegStepPin); motorLink[LeftLeg] = new AccelStepper(AccelStepper::FULL2WIRE, LeftLegDirPin, LeftLegStepPin); motorLink[RightFoot] = new AccelStepper(AccelStepper::FULL2WIRE, RightFootDirPin, RightFootStepPin); motorLink[LeftFoot] = new AccelStepper(AccelStepper::FULL2WIRE, LeftFootDirPin, LeftFootStepPin); motorLink[Balance] = new AccelStepper(AccelStepper::FULL2WIRE, BalanceDirPin, BalanceStepPin); for (int i = 0; i < 10; i++) awakenByInterruptPin[i] = false; // attachInterrupt(arduinoInterrupt, intCallBack, FALLING); } void intCallBack() { awakenByInterrupt = true; } void handleInterrupt() { Serial.println("InHandleInterrupt"); pin = mcp.getLastInterruptPin(); uint8_t val = mcp.getLastInterruptPinValue(); // we have to wait for the interrupt condition to finish // otherwise we might go to sleep with an ongoing condition and never wake up again. // as, an action is required to clear the INT flag, and allow it to trigger again. // see datasheet for datails. while ( ! (mcp.digitalRead(4) && mcp.digitalRead(5) && mcp.digitalRead(6) && mcp.digitalRead(7) )); // and clean queued INT signal cleanInterrupts(); Serial.println("OutHandleInterrupt"); } // handy for interrupts triggered by buttons // normally signal a few due to bouncing issues void cleanInterrupts() { EIFR = 0x01; awakenByInterrupt = false; } void matrix () { for (int i = 1; i <= 4; i++) // { mcp.digitalWrite(rowPins[i - 1], LOW); // for (int j = 1; j <= 4; j++) // { if (mcp.digitalRead(colPins[j - 1]) == LOW) // { mcp.setupInterruptPin(colPins[j - 1], RISING); switch (keys[i - 1][j - 1]) { case '2': Rotate(Balance, 1, j, 6000, 1000); Serial.println("2"); break; case '3': Serial.println("3"); Rotate(Balance, 0, j, 6000, 2000); break; case '1': Serial.println("1"); Rotate(LeftLeg, 1, j, 6000, 5000); break; case '4': Serial.println("4"); Rotate(LeftLeg, 0, j, 6000, 5000); break; case 'A': Serial.println("A"); Rotate(RightLeg, 1, j, 6000, 5000); break; case 'B': Serial.println("B"); Rotate(RightLeg, 0, j, 6000, 5000); break; case '*': Serial.println("^"); Rotate(LeftFoot, 1, j, 60, 50); break; case '0': Serial.println("0"); Rotate(LeftFoot, 0, j, 60, 50); break; case '#': Serial.println("#"); Rotate(RightFoot, 1, j, 60, 50); break; case 'D': Serial.println("D"); Rotate(RightFoot, 0, j, 60, 50); break; case '5': break; case '6': break; case '7': break; case '8': break; case '9': break; case 'C': break; } } mcp.setupInterruptPin(colPins[j - 1], FALLING); } mcp.digitalWrite(rowPins[i - 1], HIGH); // } } void loop() { while (!awakenByInterrupt) matrix(); if (awakenByInterrupt) handleInterrupt(); delay(500); Serial.println("delay(500)"); }Что будет если перед delay(500); дописать else?
В #155 попечатайте состояния "входов" MCP-шки. Эта конструкция лично мне не нравится.
В #155 попечатайте состояния "входов" MCP-шки. Эта конструкция лично мне не нравится.
"всей свадьбе невеста нравится, а жениху нет" )))
А по существу, на таких конструкциях и влетаешь ...
Инструкция в строке 248, на мой взгляд, не имеет смысла. Если вышли из цикла - значит awakenByInterrupt не ложь (не равно 0).