Выход устанавливается на «низкий», когда новая переменная в буфере

Я хотел бы включать и выключать выходы двух контактов на моем Arduino независимо друг от друга. Однако пока все мои попытки не увенчались успехом.

Моя текущая идея — сохранить статус (который я выбрал равным 0 как «низкий» и «высокий» как 1) каждого из выводов в целочисленном массиве, а затем изменить статус вывода в зависимости от записи. в переменной. Однако записи в переменной всегда возвращаются к 0, и я не знаю, почему это происходит.

Это мой код Arduino

const byte numChars = 32;
byte receivedChars[numChars];
boolean newData = false;
const int num_of_pins=2;
int output_pins[num_of_pins]={22,26};
int status_pins[num_of_pins]={0,0};


void setup() {
    int ii=0;
    Serial.begin(9600);
    for(ii=0; ii<num_of_pins; ii++){      
        pinMode(output_pins[ii],OUTPUT);      
    }


}

void loop() {
    recvWithStartEndMarkers();
    chooseFunction();   
}

void chooseFunction(){
  if (receivedChars[0]==0){
    shutter();
    }
}

void shutter(){
        // получаем номер контакта
        int pin_number_rcvd;
        int ii;
        int pin_status_rcvd;
        pin_number_rcvd=receivedChars[1];
        pin_status_rcvd=receivedChars[2];
        //проверяем все состояния контактов, включаем и выключаем
        for (ii=0; ii<num_of_pins; ii++){
          if (pin_number_rcvd==output_pins[ii]){
            status_pins[ii]=pin_status_rcvd;
          }
          if (status_pins[ii]==0){
            digitalWrite(output_pins[ii],LOW);
          }
          if (status_pins[ii]==1){
            digitalWrite(output_pins[ii],HIGH);
          }
        }
}

void recvWithStartEndMarkers() {
    static boolean recvInProgress = false;
    static byte ndx = 0;
    byte startMarker = 8;
    byte endMarker = 9;
    byte rc;


    while (Serial.available() > 0 && newData == false) {
        rc = Serial.read();

        if (recvInProgress == true) {
            if (rc != endMarker) {
                receivedChars[ndx] = rc;
                ndx++;
                if (ndx >= numChars) {
                    ndx = numChars - 1;
                }
            }
            else {
                receivedChars[ndx] = '\0'; // завершаем строку
                recvInProgress = false;
                ndx = 0;
                newData = true;
            }
        }

        else if (rc == startMarker) {
            recvInProgress = true;
        }
    }
}

Я использую pyserial для отправки входных данных в Arduino. мой код на Python:

import serial
import time, struct, sys
ser=serial.Serial('COM17', 9600, timeout=10)
time.sleep(2)
ser.reset_input_buffer()
ser.reset_output_buffer()
pin_number= int(sys.argv[1])
high_or_low=int(sys.argv[2])

ser.write(struct.pack('>5B',8,1,pin_number,high_or_low,9))

Я использую ArduinoDue вместе с IDE Arduino.

, 👍0

Обсуждение

Возможно, это не так, но вы ожидаете: receivedChars[0]==0, но ser.write(struct.pack('>5B',8,1,pin_number,high_or_low,9)) отправляется (например, это 1, а не 0), @KIIV

спасибо за Ваш ответ. К сожалению, это ничего не меняет, @anonymous

вы оставили нам некоторую информацию... следующее описание не объясняет, почему используется скрипт Python.... Я хотел бы включать и выключать выходы двух контактов на моем Arduino независимо друг от друга. , @jsotola

Это правда. Простите за это. Я хочу включать и выключать вывод на плате с помощью Python, например, я хочу отправить данные на Arduino с помощью pyserial, сообщающего Arduino включить или выключить вывод на определенном выводе., @anonymous

Кажется, я понял проблему, но до сих пор не знаю, как ее решить. Проблема в том, что всякий раз, когда я хочу включить или выключить вывод, я перезапускаю скрипт Python, который полностью сбрасывает Arduino, и поэтому вывод на всех других каналах отключается., @anonymous


1 ответ


1

Ваша проблема заключается в одном сложном варианте ком-соединения Arduino. Когда вы снова открываете COM-порт, к которому подключен Arduino, ваш Arduino автоматически сбрасывается.

Вот обходной путь от arduino.cc:

Отключение AutoResetOnSerialConnection

Простой способ, не требующий любое постоянное изменение конфигурации вашего оборудования или программного обеспечения изменения:

Вставьте резистор сопротивлением 120 Ом в разъемы между 5 В и сбросом (вы можете найдите их и на разъеме ISP). 120 сложно найти, так что просто объединить резисторы. Не опускайтесь ниже 110 Ом или выше 124 Ом. не делайте этого с подключенным программатором ISP. Ты можешь просто вытащить резистор, если вы хотите вернуть автоматический сброс.

http://playground.arduino.cc/Main/DisablingAutoResetOnSerialConnection

Или вы можете просто изменить свой скрипт, чтобы иметь возможность начать его заново, не открывая его повторно. Например, используйте там цикл и команду выхода, чтобы завершить этот цикл:

try:
    while True:
        do_something()
except KeyboardInterrupt:
    pass

https://stackoverflow.com/questions/13180941 /как-завершить-цикл-пока-нажатием клавиши Замените do_something() на эту часть вашего кода:

ser.reset_input_buffer()
ser.reset_output_buffer()
pin_number= int(sys.argv[1])
high_or_low=int(sys.argv[2])

ser.write(struct.pack('>5B',8,1,pin_number,high_or_low,9))

Надеюсь, я выразился достаточно ясно.

,