Arduino Uno不想写变量
Arduino Uno does not want to write variable
我正在写一个小草图来读取传感器值并将它们打印在 LCD 屏幕上。
直到现在这都很好用,我不记得有什么改变,但突然我的 Arduino 不想再改变 ringbuf 变量的值,它现在总是在 8224。
这些是代码中最相关的部分:
const int RING_SIZE = 5;
double ringbuf[RING_SIZE]; // array for the ring buffer
unsigned int ringpos = 0; // position in the ring buffer - this will always be 8224 for some reason
// in loop()
ringbuf[ringpos] = readSensor();
ringpos++;
if (ringpos >= RING_SIZE) {
ringpos = 0;
}
完整代码如下:
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Keypad.h>
#include <stdio.h>
int readpin = A2;
int irpin = 9;
const int BUFFER_SIZE = 20;
int buf[BUFFER_SIZE];
const int RING_SIZE = 5;
unsigned int ringpos = 0;
double ringbuf[RING_SIZE];
unsigned long lastRedTime = millis();
char text[20];
const byte ROWS = 4;
const byte COLS = 3;
const unsigned long BACKLIGHT_DURATION = 5000;
const double THRESHOLD = 245;
const double wattPerTurn = 1.666666667;
double lastUsage = 0;
bool currentState = LOW;
char keys[ROWS][COLS] = {{'1', '2', '3'},
{'4', '5', '6'},
{'7', '8', '9'},
{'*', '0', '#'}
};
byte rowPins[] = {5, 4, 3, 2};
byte colPins[] = {8, 7, 6};
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
LiquidCrystal_I2C lcd(0x20, 16, 2);
unsigned long lastKey = millis();
int turns = 0;
void setup() {
Serial.begin(9600);
lcd.init();
lcd.backlight();
lcd.home();
pinMode(irpin, OUTPUT);
analogReference(DEFAULT);
digitalWrite(irpin, HIGH);
}
void loop() {
Serial.print(ringpos);
Serial.println();
ringbuf[ringpos] = readSensor();
ringpos++;
if (ringpos >= RING_SIZE) {
ringpos = 0;
}
double value = getAverage();
if (value < THRESHOLD && currentState == HIGH) {
currentState = LOW;
lastUsage = wattPerTurn / (double) ((millis() - lastRedTime) / 1000) * (double) 3600;
turns ++;
lastRedTime = millis();
lcd.clear();
lcd.setCursor(10, 0);
lcd.print("rot");
}
if (value > THRESHOLD && currentState == LOW) {
currentState = HIGH;
lcd.clear();
lcd.setCursor(10, 0);
lcd.print("silber");
}
lcd.setCursor(0, 0);
sprintf(text, "%i W", lastUsage);
lcd.print(text);
lcd.setCursor(0, 1);
sprintf(text, "s: %i, t: %i Wh ", (int) value, (int) (((double) turns) * wattPerTurn));
lcd.print(text);
delay(20);
}
double getRelative(int r) {
int v = ringpos + r;
while (v < 0) {
v += RING_SIZE;
}
while (v >= RING_SIZE) {
v -= RING_SIZE;
}
return ringbuf[v];
}
double getAverage() {
double sum = 0;
for (int i = 0; i < RING_SIZE; i++) {
sum += ringbuf[i];
}
return sum / (double) RING_SIZE;
}
double readSensor() {
for (int i = 0; i < BUFFER_SIZE; i++) {
buf[i] = analogRead(readpin);
}
int sum = 0;
for (int i = 0; i < BUFFER_SIZE; i++) {
sum += buf[i];
}
return (double) sum / (double) BUFFER_SIZE;
}
我可能漏掉了一些非常愚蠢的东西,但我不知道为什么它会停止工作。我还在另一个 Arduino 上测试了这个,同样的事情发生了。
请更新问题以直接包含所有相关代码,而不是在 pastie 上链接到它。错误不在您在此处显示的代码中,而是您的 text
变量
char text[10];
对于
来说太短了
sprintf(text, "s: %i, t: %i Wh ", (int) value, (int) (((double) turns) * wattPerTurn));
你稍后再做,所以这会在 text
之外写入恰好位于 RAM 中 text
后面的变量。想必,ringpos
恰好属于一种情况下被覆盖的那些,而另一种情况下则不会,但这当然会导致UB,无论哪种方式都是不可靠的。
要修复它,请使 text
足够大。
我正在写一个小草图来读取传感器值并将它们打印在 LCD 屏幕上。 直到现在这都很好用,我不记得有什么改变,但突然我的 Arduino 不想再改变 ringbuf 变量的值,它现在总是在 8224。
这些是代码中最相关的部分:
const int RING_SIZE = 5;
double ringbuf[RING_SIZE]; // array for the ring buffer
unsigned int ringpos = 0; // position in the ring buffer - this will always be 8224 for some reason
// in loop()
ringbuf[ringpos] = readSensor();
ringpos++;
if (ringpos >= RING_SIZE) {
ringpos = 0;
}
完整代码如下:
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <Keypad.h>
#include <stdio.h>
int readpin = A2;
int irpin = 9;
const int BUFFER_SIZE = 20;
int buf[BUFFER_SIZE];
const int RING_SIZE = 5;
unsigned int ringpos = 0;
double ringbuf[RING_SIZE];
unsigned long lastRedTime = millis();
char text[20];
const byte ROWS = 4;
const byte COLS = 3;
const unsigned long BACKLIGHT_DURATION = 5000;
const double THRESHOLD = 245;
const double wattPerTurn = 1.666666667;
double lastUsage = 0;
bool currentState = LOW;
char keys[ROWS][COLS] = {{'1', '2', '3'},
{'4', '5', '6'},
{'7', '8', '9'},
{'*', '0', '#'}
};
byte rowPins[] = {5, 4, 3, 2};
byte colPins[] = {8, 7, 6};
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
LiquidCrystal_I2C lcd(0x20, 16, 2);
unsigned long lastKey = millis();
int turns = 0;
void setup() {
Serial.begin(9600);
lcd.init();
lcd.backlight();
lcd.home();
pinMode(irpin, OUTPUT);
analogReference(DEFAULT);
digitalWrite(irpin, HIGH);
}
void loop() {
Serial.print(ringpos);
Serial.println();
ringbuf[ringpos] = readSensor();
ringpos++;
if (ringpos >= RING_SIZE) {
ringpos = 0;
}
double value = getAverage();
if (value < THRESHOLD && currentState == HIGH) {
currentState = LOW;
lastUsage = wattPerTurn / (double) ((millis() - lastRedTime) / 1000) * (double) 3600;
turns ++;
lastRedTime = millis();
lcd.clear();
lcd.setCursor(10, 0);
lcd.print("rot");
}
if (value > THRESHOLD && currentState == LOW) {
currentState = HIGH;
lcd.clear();
lcd.setCursor(10, 0);
lcd.print("silber");
}
lcd.setCursor(0, 0);
sprintf(text, "%i W", lastUsage);
lcd.print(text);
lcd.setCursor(0, 1);
sprintf(text, "s: %i, t: %i Wh ", (int) value, (int) (((double) turns) * wattPerTurn));
lcd.print(text);
delay(20);
}
double getRelative(int r) {
int v = ringpos + r;
while (v < 0) {
v += RING_SIZE;
}
while (v >= RING_SIZE) {
v -= RING_SIZE;
}
return ringbuf[v];
}
double getAverage() {
double sum = 0;
for (int i = 0; i < RING_SIZE; i++) {
sum += ringbuf[i];
}
return sum / (double) RING_SIZE;
}
double readSensor() {
for (int i = 0; i < BUFFER_SIZE; i++) {
buf[i] = analogRead(readpin);
}
int sum = 0;
for (int i = 0; i < BUFFER_SIZE; i++) {
sum += buf[i];
}
return (double) sum / (double) BUFFER_SIZE;
}
我可能漏掉了一些非常愚蠢的东西,但我不知道为什么它会停止工作。我还在另一个 Arduino 上测试了这个,同样的事情发生了。
请更新问题以直接包含所有相关代码,而不是在 pastie 上链接到它。错误不在您在此处显示的代码中,而是您的 text
变量
char text[10];
对于
来说太短了sprintf(text, "s: %i, t: %i Wh ", (int) value, (int) (((double) turns) * wattPerTurn));
你稍后再做,所以这会在 text
之外写入恰好位于 RAM 中 text
后面的变量。想必,ringpos
恰好属于一种情况下被覆盖的那些,而另一种情况下则不会,但这当然会导致UB,无论哪种方式都是不可靠的。
要修复它,请使 text
足够大。