Прерывания в Ардуино через Serial
- Войдите на сайт для отправки комментариев
Добрый день, у меня есть код, связывающий ардуино и датчиком gy-521:
#include<Wire.h>
const int MPU=0x68;
int16_t AcX,AcY,AcZ;
unsigned long time;
void setup(){
Wire.begin();
Wire.beginTransmission(MPU);
Wire.write(0x6B);
Wire.write(0);
Wire.endTransmission(true);
Serial.begin(19200);
while (!Serial);// wait for serial port to connect. Needed for native USB port only
}
void loop(){
Wire.beginTransmission(MPU);
Wire.write(0x3B);
Wire.endTransmission(false);
Wire.requestFrom(MPU,12,true);
AcX=Wire.read()<<8|Wire.read();
AcY=Wire.read()<<8|Wire.read();
AcZ=Wire.read()<<8|Wire.read();
time = millis();
Serial.print(time);Serial.print(",");Serial.print(AcX);Serial.print(",");Serial.print(AcY);Serial.print(",");Serial.println(AcZ);
delay(0);
}
Дальше я связываю ардуино и питоном, и обрабатываю полученные данные уже в питоне.
with serial.Serial('/dev/tty.usbmodem143101', 19200, timeout = 1) as ser:
_____value = ser.readline()
_____value = value.decode('utf-8', 'ignore')
...сохраняю значения в массив...
ser.close() //закрываю порт
Существует проблема: после N-итераций обработки (периодически вызываю функцию считывания) данные с ардуино перестают приходить (приходит пустая строка)
Мне подсказали, что проблема в том, что нет прерывания. Соотвественно мой вопрос: как правильно написать (и куда вставить) функцию прерывания по пришедшему символу?
я думала сделать так:
#include<Wire.h>
const int MPU=0x68;
int16_t AcX,AcY,AcZ;
unsigned long time;
void setup(){
Wire.begin();
Wire.beginTransmission(MPU);
Wire.write(0x6B);
Wire.write(0);
Wire.endTransmission(true);
Serial.begin(19200);
while (!Serial);// wait for serial port to connect. Needed for native USB port only
}
void loop(){
Wire.beginTransmission(MPU);
Wire.write(0x3B);
Wire.endTransmission(false);
Wire.requestFrom(MPU,12,true);
AcX=Wire.read()<<8|Wire.read();
AcY=Wire.read()<<8|Wire.read();
AcZ=Wire.read()<<8|Wire.read();
time = millis();
Serial.print(time);Serial.print(",");Serial.print(AcX);Serial.print(",");Serial.print(AcY);Serial.print(",");Serial.println(AcZ);
delay(0);
if (Serial.available()) {
char incom = Serial.read()
// ???????
}
}
но что писать вместо "????"
Прерывание по пришедшему символу в ардуино есть всегда. Код со стороны питона очень странный. Порт не надо постоянно открывать и закрывать. И синхронизации какой-то нет, если открылись посередине строки, то получится мусор.
Проблема не в ардуине. Попробуйте просто в терминальную программу вывод. Он останавливается?
Прерывание по пришедшему символу в ардуино есть всегда. Код со стороны питона очень странный. Порт не надо постоянно открывать и закрывать. И синхронизации какой-то нет, если открылись посередине строки, то получится мусор.
1) оно может быть и есть,но меня интересует, чтобы он перестал считывать данные
2) код странный, потому что это последний костыль, которым я пыталась избежать проблему считывания пустой строки. до этого я один раз только открывала порт
3) синхронизация есть дальше по коду в питоне, то есть я обхожу все данные, которые меня не устраивают
Проблема не в ардуине. Попробуйте просто в терминальную программу вывод. Он останавливается?
я не очень поняла, про что вы
вот код для питона, если что with serial.Serial('/dev/tty.usbmodem143101', 19200, timeout = 1) as ser: time.sleep(5) while i < self.time_observation: value = ser.readline() value = value.decode('utf-8', 'ignore') if value == '': #если данных нет print('empty') self.sensors() #перезапустить функцию v = value.rstrip().replace(" ", "") #разделить данные и тд и тп result = [x.strip() for x in v.split(',')] if len(result) == 4: #интересуют только "целые" строчки if i == 0: try: self.time_start = float(result[0]) except ValueError: print('error:', result[0]) pass try: array_105_x.append(float(result[1])) array_105_y.append(float(result[2])) array_105_z.append(float(result[3])) i+=1 pbar.update(1) except ValueError: print(result) continue #ser.write(str(1).encode()) #print ("RECIEVED BACK:",ser.readline().decode()) pbar.close() ser.close()я попыталась сделать методом тру-фолс, но оно не работает) то есть данные сначала НЕ считываются, стоит отправить "0": беспрерывный поток данных
#include<Wire.h> const int MPU=0x68; int16_t AcX,AcY,AcZ; unsigned long time; bool allow = false; void setup(){ Wire.begin(); Wire.beginTransmission(MPU); Wire.write(0x6B); Wire.write(0); Wire.endTransmission(true); Serial.begin(19200); while (!Serial);// wait for serial port to connect. Needed for native USB port only } void loop(){ if (allow == true){ Wire.beginTransmission(MPU); Wire.write(0x3B); Wire.endTransmission(false); Wire.requestFrom(MPU,12,true); AcX=Wire.read()<<8|Wire.read(); AcY=Wire.read()<<8|Wire.read(); AcZ=Wire.read()<<8|Wire.read(); time = millis(); Serial.print(time);Serial.print(",");Serial.print(AcX);Serial.print(",");Serial.print(AcY);Serial.print(",");Serial.println(AcZ); delay(0); } } void serialEvent() { while (Serial.available()){ char incom = Serial.read(); Serial.print(incom); if (incom == 0){ allow = false; } else { allow = true; } } }И даже в родной ардуиновский терминал. Если нажать на кнопку монитор порта в правом верхнем углу ИДЕ, то весь вывод принта будет выводится в это окно. Если вывод программы идет без пустых строк - проблема в принимающей стороне. Если много раз открывать - закрывать порт, он в конце концов глюкает.
в ардуино все работает без проблем, в питоне - если принимать беспрерывно данные - тоже
я сейчас переписала код, теперь он работает в порте ардуино (по 1 - считывает данные, по 0 - нет), то есть реально происходит прерывание.
#include<Wire.h> const int MPU=0x68; int16_t AcX,AcY,AcZ; unsigned long time; bool allow = false; //int incom = 0; void setup(){ Wire.begin(); Wire.beginTransmission(MPU); Wire.write(0x6B); Wire.write(0); Wire.endTransmission(true); Serial.begin(19200); while (!Serial);// wait for serial port to connect. Needed for native USB port only } void loop(){ if (allow){ Wire.beginTransmission(MPU); Wire.write(0x3B); Wire.endTransmission(false); Wire.requestFrom(MPU,12,true); AcX=Wire.read()<<8|Wire.read(); AcY=Wire.read()<<8|Wire.read(); AcZ=Wire.read()<<8|Wire.read(); time = millis(); //Serial.println("Allow:");Serial.print(incom);Serial.print("///"); Serial.print(time);Serial.print(",");Serial.print(AcX);Serial.print(",");Serial.print(AcY);Serial.print(",");Serial.println(AcZ); delay(0); } } void serialEvent() { while (Serial.available()){ int incom = Serial.read() - '0'; //delay(10); Serial.println(incom); if (incom == 0){ allow = false; delay(100); } if (incom == 1){ allow = true; delay(100); } } }теперь уже реально проблема в принимающей стороне. потому что не удается отослать команды:
Если инициализировать все сначала
print(msg)