Как заставить Arduino отвечать на непрерывный поток данных от Python?

Пытаюсь сделать тюнер. К плате Arduino Uno подключены 3 светодиода, каждый из которых соответствует одной ситуации (слишком высокая, низкая или правильная высота). Python обрабатывает обнаружение заметки в соответствии с входом микрофона и определяет, какой светодиод должен быть включен, но, поскольку это живой тюнер, Python отправляет информацию довольно быстро. Я понял, как включать светодиоды по одному и держать его включенным до тех пор, пока входной сигнал не меняется, но он работает только на низкой скорости, когда я делаю это вручную, с помощью такой программы Python:

code=1
while code!=0:
    code=input("Code?")
    ser.write(code.encode('utf-8')) 

Если я попробую это с кодом Python, например:

code= '5'
while 1:
    ser.write(code.encode('utf-8'))

тогда светодиоды просто не горят.

Вот мой код Arduino:

int hauteur = 0;
void setup() {
    pinMode (2, OUTPUT); //red pin
    pinMode (6, OUTPUT); //green pin
    pinMode (5, OUTPUT); //yellow pin
    Serial.begin(9600);
}

void loop() {
    if(Serial.available ()) {
        hauteur = Serial.parseInt();

        while (hauteur==2) {
            (digitalWrite(2,HIGH));
            if (Serial.available ()) {
                hauteur=Serial.parseInt();
            }
        }
        digitalWrite(2,LOW);

        while (hauteur==5){
            (digitalWrite(5,HIGH));
            if (Serial.available ()) {
                hauteur=Serial.parseInt();
            }
        }
        digitalWrite(5,LOW);

        while (hauteur==6){
            (digitalWrite(6,HIGH));
            if (Serial.available ()) {
                hauteur=Serial.parseInt();
            }
        }
        digitalWrite(6,LOW);

        Serial.flush();
    }
}

Если 2, 5 или 6 отправляются Python с достаточным промежутком времени между ними, тогда плата выполняет то, что должна делать, и включает соответствующий светодиод. Однако отправлено слишком быстро, больше ничего не происходит. Как я могу сократить этот необходимый промежуток времени, чтобы получить изменение освещения в реальном времени в соответствии с тем, что отправлено Python?


person sheyy_dt    schedule 16.06.2018    source источник


Ответы (2)


Arduino получает от программы Python. Чтобы он не отставал, он должен опрашивать последовательную линию быстрее, чем Python отправляет команды.

Другими словами, вам нужно замедлить последовательные команды Python, поскольку Arduino не может успевать (да, вы сбрасываете строку на стороне Arduino, но лучше просто всегда ждать любые входящие данные).

Поэтому я бы переписал ваш код Python с некоторыми time.sleep вызовами:

while 1:
    #code to modify the value of `code`...
    ser.write(code.encode('utf-8'))
    time.sleep(0.1)

Что касается стороны Arduino, я думаю, вы неправильно понимаете, как работает функция digitalWrite. После включения или выключения булавки он остается в этом состоянии, пока вы не переключите его в другое состояние. Это означает, что вам не нужно постоянно указывать ему, чтобы он оставался в while цикле, вы можете просто один раз сказать ему, в каком состоянии он должен быть.

Это упрощает ваш код:

int hauteur;
void setup() {
    pinMode(2, OUTPUT); //red pin
    pinMode(6, OUTPUT); //green pin
    pinMode(5, OUTPUT); //yellow pin
    Serial.begin(9600);
}

void loop() {
    if (Serial.available()) {
        hauteur = Serial.parseInt();
        digitalWrite(2, hauteur == 2);
        digitalWrite(5, hauteur == 5);
        digitalWrite(6, hauteur == 6);
        Serial.flush()
    }
}

Поэтому вместо того, чтобы использовать какие-либо ненужные if или while, вы можете просто установить состояние каждого светодиода для оценки того, равно ли полученное целое число этому выводу.

person Joe Iddon    schedule 16.06.2018

Я не думаю, что у Arduino должна быть проблема с тем, как быстро вы отправляете данные. Последовательные данные немного медленные. При 9600 бод это всего около 960 байт / сек (8 бит плюс стартовые / стоповые биты).

Также обратите внимание, что на Arduino digitalWrite может работать медленно. Чтобы получить более быстрые результаты, см .: https://www.arduino.cc/en/Reference/PortManipulation

Попробуй это:

// Create an array so we can use a loop
// Another advantage is you can easily add leds
int leds[] = {2,5,6};
const int num_leds = sizeof(leds)/sizeof(leds[0]); // = 3
void loop()
{
    if (Serial.available()) {
        hauteur = Serial.parseInt();
        // Turn hauteur ON and others OFF
        for (int i = 0; i < num_leds; i++) {
            digitalWrite(leds[i], leds[i] == hauteur ? HIGH : LOW);
        }
    }
}
person Johnny Mopp    schedule 16.06.2018