我用Arduino做了一个有趣的矩阵骰子,我打破了我的大脑让中断正常工作。我有两个中断,一个用于掷骰子(state_change),另一个用于睡眠Arduino(arduino_off)。玩骰子的中断是可以的,但我在关机后唤醒Arduino有一些问题。我尝试使用HIGH,LOW和RAISE选项抛出中断。最好的配置似乎保持高引脚并将其接地以引发中断。我在我的电脑和Arduino之间使用USB电压和电流表。如果我通过if语句中的数字写入将中断设置为LOW,我看到我可以关闭Arduino。问题是唤醒它。我认为用另一个数字写入是不可能的,因为循环停止了,但是如果我用按钮手动尝试它有时会唤醒但再次睡觉,就好像有一个弹跳问题。
#include <MaxMatrix.h>
#include <avr/pgmspace.h>
#include <avr/sleep.h>
#include <avr/power.h>
const byte A[] = {
4, 8, B1111110, B0010001, B0010001, B1111110 //A
};
const byte empty[] = {
8, 8, B00000000, B00000000, B00000000, B00000000,
B00000000, B00000000, B00000000, B00000000 // all leds off
};
const byte full[] = {
8, 8, B11111111, B11111111, B11111111, B11111111,
B11111111, B11111111, B11111111, B11111111 // all leds on
};
const byte face[] = {
8, 8, B00000000, B00000000, B00000000, B00011000,
B00011000, B00000000, B00000000, B00000000, // ONE
8, 8, B00000011, B00000011, B00000000, B00000000,
B00000000, B00000000, B11000000, B11000000, // TWO
8, 8, B11000000, B11000000, B00000000, B00011000,
B00011000, B00000000, B00000011, B00000011, // THREE
8, 8, B11000011, B11000011, B00000000, B00000000,
B00000000, B00000000, B11000011, B11000011, // FOUR
8, 8, B11000011, B11000011, B00000000, B00011000,
B00011000, B00000000, B11000011, B11000011, // FIVE
8, 8, B11011011, B11011011, B00000000, B11011011,
B11011011, B00000000, B11011011, B11011011, // SIX
};
int din_pin = 4;
int load_pin = 5;
int clock_pin = 6;
int interrupt_pin_real_one = 1; //atmega = PD3(int1) = 1
//arduino mapping = pin 3 (write the real one)
int interrupt_pin_real_zero = 0;
int interrupt_pin_mapped_one = 3;
int interrupt_pin_mapped_zero = 2;
int matrix_number = 4;
// max tollerance to needed to change state
volatile int bounce_tol = 300;
volatile int bounce = 0; // count bouncing time/button pressed
long time = 0; // store the timestamp;
// max time before cpu sleep
// 60000 = 1 minute
// 1000 = 1 second
long time_limit = 1000 * 5;
int i = 0;
volatile int state = LOW;
// check standby mode
// normal = false, standby enabled = true;
boolean low_profile = false;
boolean first_run = true; // check if the dice never rolled
boolean one_loop = true; // to execute the if statement only ones
MaxMatrix m(din_pin, load_pin, clock_pin, matrix_number);
void setup(){
Serial.begin(9600);
m.init();
m.setIntensity(15); // dot matix intensity 0-15
pinMode(din_pin,OUTPUT);
pinMode(load_pin,OUTPUT);
pinMode(clock_pin,OUTPUT);
pinMode(interrupt_pin_mapped_one, INPUT);
pinMode(interrupt_pin_mapped_zero, INPUT);
// no pull up needed
// BE CAREFULL IN PCB DESIGN NOT CONNECT TO GND
digitalWrite(interrupt_pin_mapped_one, HIGH);
digitalWrite(interrupt_pin_mapped_zero, HIGH);
attachInterrupt(interrupt_pin_real_one, state_changer, LOW);
attachInterrupt(interrupt_pin_real_zero, arduino_off, LOW);
}
// toggle power down / up
void arduino_off(){
set_sleep_mode(SLEEP_MODE_IDLE); // sleep mode is set here
sleep_enable(); // enables the sleep bit in the mcucr register
// so sleep is possible. just a safety pin
/* Now it is time to enable an interrupt. We do it here so an
* accidentally pushed interrupt button doesn't interrupt
* our running program. if you want to be able to run
* interrupt code besides the sleep function, place it in
* setup() for example.
*
* In the function call attachInterrupt(A, B, C)
* A can be either 0 or 1 for interrupts on pin 2 or 3.
*
* B Name of a function you want to execute at interrupt for A.
*
* C Trigger mode of the interrupt pin. can be:
* LOW a low level triggers
* CHANGE a change in level triggers
* RISING a rising edge of a level triggers
* FALLING a falling edge of a level triggers
*
* In all but the IDLE sleep modes only LOW can be used.
*/
attachInterrupt(interrupt_pin_real_zero, arduino_off, HIGH);
sleep_mode(); // here the device is actually put to sleep!!
// THE PROGRAM CONTINUES FROM HERE AFTER WAKING
sleep_disable(); // first thing after waking from sleep:
// disable sleep...
detachInterrupt(interrupt_pin_real_zero);
// wakeUpNow code will not be executed
// during normal running time.
}
// dice rooollll!!!!!
void state_changer(){
if(bounce >= bounce_tol){
if(low_profile == true){
//CLKPR = 0x01;
low_profile = false;
}
Serial.print("rolling \n");
//digitalWrite(interrupt_pin_mapped_zero, LOW);
state = !state;
bounce = 0;
}
bounce++;
}
void magic_box(int sleep){
int num_1 = random(6);
int num_2 = random(6);
int num_3 = random(6);
int num_4 = random(6);
m.writeSprite(0, 0, &face[num_1*10]);
m.writeSprite(8, 0, &face[num_2*10]);
m.writeSprite(16, 0, &face[num_3*10]);
m.writeSprite(24, 0, &face[num_4*10]);
delay(sleep);
}
void rolling(){
for(i=0;i<=10;i++){
magic_box(50);
}
for(i=0;i<=6;i++){
magic_box(200);
}
for(i=0;i<=2;i++){
magic_box(500);
}
}
void clear_matrix(){
m.writeSprite(0, 0, empty);
m.writeSprite(8, 0, empty);
m.writeSprite(16, 0, empty);
m.writeSprite(24, 0, empty);
}
void loop() {
//digitalWrite(interrupt_pin_mapped_zero, HIGH);
if(((millis() - time) >= time_limit)
&& first_run == false && one_loop == true){
//debug
Serial.print("stop \n");
//sleep_enable();
//energy.PowerDown();
//CLKPR = 0x04;
clear_matrix();
// throw the interrupt to powerdown the Arduino
//digitalWrite(interrupt_pin_mapped_zero, LOW);
//debug
Serial.print("after stop \n");
low_profile = true;
one_loop = false;
}
if(state == HIGH){
if(bounce < bounce_tol){
//digitalWrite(interrupt_pin_mapped_zero, LOW);
rolling();
state = LOW;
bounce = 0;
first_run = false;
one_loop = true;
time = millis(); // time stamp of the last rolling
}
}
}
这里有视频来&#34;提出想法&#34;我所说的话。 https://youtu.be/INCNUYrVASQ
P:你能告诉我自动缩进4个空格以显示堆栈溢出中的文本代码的神秘秘密....使用一天来隔离每行而不是编码应该强调:)再见:)