Во-первых, я буду считать, что где-то в вашем коде вы зовите
blinkLED('10')
иначе вся эта дискуссия не имеет смысла.
В связи с этим, я бы изменить вашу функцию blinkLED(x)
следующим образом:
def blinkLED(x):
ser.write(x)
ser.flushOutput()
return
Во-вторых, я не полностью уверен, по этому коду:
1: void establishContact() {
2: while (Serial.available() <= 0){
3: val = Serial.parseInt();
4: Serial.flush();
5: }
6: }
Прежде всего, Я не совсем уверен, что вы думаете, что Serial.flush()
должен там делать, так как в соответствии с documentation это «Ожидает передачи o выполнить последовательные данные для завершения «, но вы ничего не отправляете на выходе Serial
.
Во-вторых, когда вы находитесь на линии 2:
на первой итерации цикла, то возможны два случая:
- А. что-то доступно на
Serial
входе, поэтому Serial.available() > 0
, вы не войти в и вы не читаете val
- B. ничего не имеется на
Serial
ввода, поэтому Serial.available() == 0
, и вы вводите петлю. В настоящее время существует два подсектора:
- B.1. Если ничего не поступило на
Serial
ввода, вы продолжаете читать 0
навсегда и остаетесь в этом петле
- B.2. если что-то поступает на вход
Serial
, есть 3 суб-дела:
- B.2.I. входные данные поступают сразу после выполнения
Serial.parseInt()
, поэтому на следующей итерации цикла Serial.available() <= 0
ложна и выхода из цикла, не читая ваши val
(то есть, вы в конечном итоге в случае А.)
- В.2 .II. входные данные поступают правильно, когда вы выполняете
Serial.parseInt()
, и вы успешно разобрали все входные байты в val
. Однако в пределах ввода Serial
ничего не остается, поэтому условие Serial.available() <= 0
сохраняется, и вы остаетесь застрявшим в петле
- B.2.III. входные данные поступают правильно, когда вы выполняете
Serial.parseInt()
, и вы успешно разобрали некоторые входные байты в val
. Еще несколько байтов, которые не относятся значение Int(например \r
, \n
, \t
, пространство, буквенные символы, ...) игнорируются Serial.parseInt()
и остаются в Serial
входного буфера. Поэтому на следующем цикле итерация Serial.available() <= 0
ошибочна, и вы выходите из цикла.
Когда вы звоните blinkLED('10')
вы в конечном итоге в одном из следующих случаев: А., B.2.I. или B.2.II.. Это объясняет, почему вы не видите мигания: либо вы все еще застряли в цикле, либо вы прошли мимо него, не прочитав ничего, и у вас все еще есть val == 0
.
Дело B.2.III. - единственная ситуация, в которой вы в конечном итоге получаете рабочий эскиз. Это то, что происходит, когда вы используете Arduinoсерийный монитор, поскольку последний посылает дополнительный \n
(или \r\n
? Я не помню ..) по умолчанию при нажатии enter
на клавиатуре.
Так что я думаю, что это объясняет, почему ваша эскиза работы при использовании серийного монитора, но не тогда, когда вы используете питона код. Быстрый тест будет изменить blinkLED(x)
следующим образом:
def blinkLED(x):
ser.write(x)
ser.write('\n')
ser.flushOutput()
return
Примечания: тот факт, что при использовании монитора последовательного порта работает на несколько тестов, или даже pyserial
может работать с этим исправлением, не означает, что ваш эскиз теперь правильный и что он всегда будет работать. Фактически, код может все еще сбой, например. если Serial.available > 0
слишком скоро, то вы все равно не входите в тело петли и разбираете val
.
@ArnoBozo предложил изменить establishContact()
следующим образом:
1: void establishContact() {
2: while (Serial.available() > 0){
3: val = Serial.parseInt();
4: Serial.flush();
5: }
6: }
Я думаю, что эта конструкция недостатки, а также, потому что снова у вас есть нет гарантии, что к тому времени, вы проверяете Serial.available() > 0
номер телефона: python
еще не отправили данные (или его отправка). Если это не так, то корпус просто не выполнен, и вы никогда не разбираете val
. Конечно, вы можете попробовать сыграть с delay()
, но это делает весь эскиз довольно хрупкий.
Последнее наблюдение: если вы посмотрите на documentation из Serial.parseInt()
, вы обнаружите, что:
- Синтаксический останавливается, когда никакие символы не будут считаны в течение настраиваемого времени ожидания, или считывается незначащая цифра;
- Если действительные цифры не были прочитаны при тайм-ауте (см. Серий.setTimeout()), возвращается 0;
Если проверить documentation из Serial.setTimeout()
вы обнаружите, что timeout
"по умолчанию 1000 миллисекунд". Опять же, за счет повторяются и появляться педантичными, нельзя полагаться на таймаутах и задержки в протоколе связи, если строго необходимо (например, эвристически не решили, что настало время свободных ресурсов выделенных для связи с внешним объектом, который больше не участвует в сообщении).
Таким образом, мой совет должен либо поцарапатьSerial.parseInt()
и написать собственный синтаксический анализатор, либо использовать его более надежным способом. цель вы имеете в виду:
Serial.setTimeout(0); // disables timeout
while (val == 0) { // discard any 'garbage' input
val = Serial.parseInt(); // keeps trying to read an Int
}
Этот подход является довольно жестокой(но YOLO): Arduino не перестанет пытаться разобрать int
отличается от 0
до, когда он получает один. Опять же, вам следует отправить недопустимую цифру после вашего номера (например, \n
), потому что иначе Serial.parseInt()
не будет возвращаться с timeout
в настоящее время равен 0
.
(обратите внимание, что я не проверял этот код, она также может не работать, если я неправильно истолковал некоторые части документации библиотеки.)
как вы знаете, он не работает? ожидаемый выход и фактический выход? что вы пробовали? – WhatsThePoint
Ваш код 'python' ничего не делает, и * действительно ничего не происходит *: кажется, работает нормально. * Возможно, вам не нужен вызов 'blinkLED()' где-то в вашем скрипте. –
В оболочке python я вызываю эту функцию. BlinkLED ('10 '), заставит ее мигать 10 раз. –