#arrays #string #split #arduino #processing
#массивы #строка #разделение #arduino #обработка
Вопрос:
Я отправляю 3 значения датчика из Arduino на обработку и разделяю строку на три элемента в массиве. Иногда, когда я запускаю программу, я получаю ошибку ArrayIndexOutOfBoundsException: 2, и, насколько я понимаю, это означает, что я пытаюсь получить доступ к элементу в массиве, которого там нет. Что я делаю не так?
Мой код из Processing и Arduino приведен ниже:
ОБРАБОТКА:
import processing.serial.*;
Serial port;
float background;
float r1;
int a;
int b;
int c;
PrintWriter output;
Databox Data1 = new Databox(20, 20);
Databox Data2 = new Databox(20, 190);
Databox Data3 = new Databox(20, 360);
void setup() {
size (690, 530);
port = new Serial(this, "COM3", 9600);
output = createWriter(hour() "." minute() "." second() ".txt");
}
void draw() {
background(60, 40);
Data1.drawDataboxHumi();
Data2.drawDataboxTemp();
Data3.drawDataboxMoist();
if (port.available() > 0) {
String inString = port.readStringUntil('n');
if (inString != null) {
inString = trim(inString);
String[] data = split(inString, '#');
a = int(data[0]);
b = int(data[1]);
c = int(data[2]);
output.println("Tidspunkt:" " " hour() ":" minute() ":" second() " - "
"Luftfugtighed:" a "%" " " "Temperatur:" b " " "Jordfugtighed:" " " c);
output.flush();
}
}
}
ARDUINO:
#include <dht.h>
dht DHT;
#define DHT11_PIN 7
void setup() {
Serial.begin(9600);
pinMode(A0, INPUT);
}
void loop() {
int SensorValue = analogRead(A0);
int chk = DHT.read11(DHT11_PIN);
Serial.print(DHT.humidity);
Serial.print("#");
Serial.print(DHT.temperature);
Serial.print("#");
Serial.print(SensorValue);
Serial.println("#");
delay(1500);
}
Комментарии:
1. как упоминает @ocrdu, данные могут быть потеряны или обработка может открыть порт, когда Arduino находится в середине отправки: может возникнуть ситуация, когда «пакет» может быть потерян.
if(data.length == 4)
Также дважды проверьте перед синтаксическим анализомa,b,c
Ответ №1:
Попробуйте проверить (путем печати), что port.readStringUntil('n')
возвращается точно каждый раз, и таким же образом проверьте, что от него осталось после trim()
.
Иногда может быть readStringUntil()
время ожидания, а затем возвращается 0
только строка без каких-либо #
s, которая будет split
в массив из 1 элемента. Он также может каким-то образом считывать ложные данные, оставшиеся в буфере, с тем же эффектом.
Единственный способ выяснить это — проверить inString
, как сказано выше.
Вы могли бы предотвратить ошибку во время выполнения, выполнив проверку количества элементов в String[] data
, прежде чем обращаться к отдельным элементам массива, но это не решает основную проблему. Тем не менее, это может быть достаточно хорошо для ваших целей.
Замечание:
Вам не нужно отправлять последнюю (третью) #
из Arduino; вам нужно только две для разделения Arduino String
на три части, а наличие трех #
s может привести к split
получению четырех частей. Однако n
в конце потребуется a .
Комментарии:
1. Похоже, время ожидания не истекло. Я удалил 3-й «#», но никаких видимых улучшений. Когда я его удаляю, 3-й вывод данных «sensorValue» отображается как 0 при обработке при запуске программы.
2. Выведите на экран, какой inString находится после строки String inString = port.readStringUntil(‘n’); точно, и какой inString находится после строки inString = trim(inString); Я подозреваю, что это скажет вам, что не так.
3. Кроме того, попробуйте проверить, работает ли он правильно, если вы уменьшите значение
delay()
на Arduino до 800;readStringUntil()
имеет время ожидания по умолчанию 1 сек. Также смотрите Отредактированный ответ.4. Trim, казалось, ничего не делал, поэтому я удалил его. Код основан на старом упражнении, которое я делал пару месяцев назад, так что это был просто остаток от этого. Похоже, проблема также устранена. Я вставил if-оператор if (data.length == 4){ a = int(data[0]); b = int(data[1]); c = int(data[2]); } после String[] data = split(inString, ‘#’); и, похоже, он выполнил свою работу. В массиве 4 элемента, но я не могу заставить его работать только с 3, удалив «#» в Arduino
5. Это предотвратит возникновение ошибки во время выполнения, но не решит основную проблему.