Интерфейс MicroPython ESP8266 SPI отправляет неправильные данные

Очень простая схема использует MicroPython и интерфейс SPI для подключения микроконтроллера ESP8266 к сдвиговому регистру 74HC595. Вот как я пытаюсь отправить данные:

from machine import Pin, SPI
hspi = SPI(-1, baudrate=50000, polarity=0, phase=0, sck=Pin(14), mosi=Pin(13), miso=Pin(12), bits=8)
latch_pin = Pin(15, Pin.OUT)
latch_pin.off()

def send(s):
    hspi.write(s)
    latch_pin.on()
    latch_pin.off()

Для тестирования я поместил 8 светодиодов между выходными контактами и +5 В (через резистор 100 Ом), чтобы увидеть, что происходит, и попытался отправить данные, используя эту тестовую функцию:

import time
def test_one(s):
    send(chr(int(s)))
    time.sleep(0.5) # only to be able to examine the leds after data was sent

def test():
    [test_one(s) for s in [
        '0b00000000',
        '0b10000000',
        '0b01000000',
        '0b00100000',
        '0b00010000',
        '0b00001000',
        '0b00000100',
        '0b00000010',
        '0b00000001',
        '0b01111111',
        '0b10111111',
        '0b11011111',
        '0b11101111',
        '0b11110111',
        '0b11111011',
        '0b11111101',
        '0b11111110',
        '0b11111111']]

test()

Как видите, в этом тесте есть движущиеся единицы и движущиеся нули. Результат очень интересный. Значение 0000 0000 передается как 1100 0010. После этого все значения с одним установленным битом передаются правильно. Тогда 0111 1111 снова правильный. После этого все значения снова неверны. Я проверил вывод с помощью логического анализатора, и кажется, что эти значения отправляются двумя байтами вместо одного.

Первое хорошее значение 1000 0000:

введите здесь описание изображения

Последнее значение с одним 1 битом 0000 0001 также передается нормально:

введите здесь описание изображения

Последнее хорошее значение — 0111 1111:

введите здесь описание изображения

Следующим должен быть 1011 1111, но вместо него передается 1100 0010 1011 1111. Например. вместо одного байта отправляется два байта:

введите здесь описание изображения

Моей самой первой мыслью было, что, возможно, SPI использует 7 бит вместо 8. Но это невозможно, потому что в этом случае 1000 0000 тоже должно быть неверным. (Кроме того, объект SPI был создан с параметром bits=8.) Кстати, я также пробовал аппаратный SPI (id=1), но у него была та же проблема. Так что это должно быть проблема в моей программе, а не в оборудовании, но я застрял и не могу понять это.

Функция send() использует chr() для создания одного символа. Может ли кто-нибудь объяснить, как возможно, что некоторые отдельные символы отправляются в виде двух байтов, а другие - в виде одного байта?


person nagylzs    schedule 30.12.2018    source источник
comment
Я не уверен, следует ли ожидать, что функции SPI будут напрямую управлять 74HC595, и я не пробовал это на Micropython, но chr в Python 3.x возвращает текстовую строку Unicode, а не массив байтов. Что произойдет, если вы замените send(chr(int(s))) на send(bytes([int(s)]))?   -  person nekomatic    schedule 02.01.2019
comment
Я уже сделал это с ESP8266 с Lua. 74HC595 работает с простым SPI. Так что, возможно, MicroPython действительно реализует строки Unicode, что меня ОЧЕНЬ удивляет. :-) Я проверю это в течение 2 часов.   -  person nagylzs    schedule 02.01.2019
comment
Это проверяется: chr() создаст строку UTF-8! Если я заменю его на bytes([int(s)]), то все будет работать как положено. Невероятно, что они реализовали строки UTF-8 на крошечном микроконтроллере. Пожалуйста, напишите ответ, чтобы я мог принять его.   -  person nagylzs    schedule 02.01.2019


Ответы (1)


MicroPython основан на Python 3...

MicroPython стремится реализовать стандарт Python 3.4 (с некоторыми функциями из более поздних версий) в отношении синтаксиса языка, и большинство функций MicroPython идентичны описанным в документации «Справочник по языку» по адресу docs.python.org.

... поэтому chr возвращает строку Unicode. Чтобы указать точные байты, которые будут отправлены по SPI, вам нужно предоставить методу SPI write объект bytes.

Если вы замените send(chr(int(s))) в своем коде на send(bytes([int(s)])), он должен отправить ожидаемые битовые комбинации.

person nekomatic    schedule 02.01.2019