Arduino Raspberry Pi I2C коммуникация
- Войдите на сайт для отправки комментариев
Добрый день!
Делаю систему которая следит за дверьми и окнами. На концах стоят герконы, а на рамах магниты. Если дверь открыли, то цепь размыкается и на входе (12 пин) ардуины (UNO) логический ноль.
Ардуина у меня соеденена с Raspberry Pi по средствам I2C. Вот собственно с этим и есть проблема. У меня была идея, на ардуине проверять входы (состояние герконов) и их показания записывать в массив байтов. Записать данные в массив не проблема, но вот как передать эти данные Raspberry и как их прочитать в Python на Raspberry никак не могу понять. С одним датчиком проблем нет, но вот с массивом беда.
Вот мой код для Arduino:
#include <Wire.h> #define SLAVE_ADDRESS 0x04 int state = 0; int Command =99; /* Available commands: 99 - DEFAULT: Nothing to do 1 - CHECK DOORS */ int mainDoorPin = 12; int ledPin = 13; byte systemState[8]; void setup(){ pinMode(ledPin,OUTPUT); Serial.begin(9600); Wire.begin(SLAVE_ADDRESS); digitalWrite(ledPin,LOW); Wire.onReceive(receiveData); Wire.onRequest(sendData); } void loop() { delay(100); } void receiveData(int byteCount) { while (Wire.available()) { Command = Wire.read(); } Serial.print("Received value: "); Serial.println(Command); switch (Command){ case 99: //Set system to initial state Serial.println("Initial state..."); systemState[0]=0; systemState[1]=0; break; case 1: Serial.println("Checking doors"); checkDoors(); break; } } void checkDoors() { if(systemState[0] == 0){ systemState[0] = digitalRead(mainDoorPin); systemState[1] = 0; } } void sendData(){ Wire.write(systemState,sizeof(systemState)); }
Как видно из кода, в массиве systemState у меня два значения и отправляю я Raspberry я этот массив, но получаю только первое значение.
вот для Python:
import smbus import time bus = smbus.SMBus(1) address = 0x04 def writeNumber(value): bus.write_byte(address, value) return -1 def readNumber(): number = (bus.read_byte(address)) return number while True: var = input("Enter: ") if not var: continue writeNumber(var) print "RPI: Hi Arduino, I sent you ", var time.sleep(1) number = readNumber() print "Arduino: Hey RPi, I received a digit ", number print
Перерыл уже весь интернет, ничего не нашел. Может кто-то сталкивался, как в Python прочитать массив байтов полчаемый по I2C. Или может кто на толкнет, что почитать. Спасибо.
А почему ббы Вам не использовать напрямую GPIO малинки, их там много ... Проблемы с 3.3в ? Их решить несложно... Прощщее, чем изобретать протокол для и2с...
Как то изначально не хотелось использовать машинку для этого. На малине хотелось только обрабатывать данные полученные от ардуины, и запихивать их в БД. Это раз. А второе, интересней связать два устройства и наладить связь между ними. Может видел кто статью или какой другой материал? Можно и на английском. Спасибо.
http://wiringpi.com/reference/i2c-library
гляньте на это
http://wiringpi.com/reference/i2c-library
гляньте на это
Спасибо. Судя повсему, это поможет, есть возможность считать 16-и битовое значение :)
А можно поподробнее как Raspberry Pi и Arduino связаны?
А можно поподробнее как Raspberry Pi и Arduino связаны?
>Ардуина у меня соеденена с Raspberry Pi по средствам I2C.
Если написано i2c - значит
- sda ардуины подключен к sda распбери
- scl ардуины подключен к scl распбери
- земля ардуины соединена с землей распбери
Согласование уровней - нужно
тоесть 2 ардуины к одному распбери не подключить?
хотел использовать распбери как сервера ардуины как улиенты обрабатывающие инфу от датчиков
Разрешаю подключить.
А если серьезно, почитайте про i2c.
Можно подключить, конешн.
почитать я почитал, но страшновато эксперементировать
Подниму среди уважаемых читателей тему.
Пытался повторить разные варианты с разных источников,
но не всё гладко в нашем королевстве.
Так что есть повод поделиться опытом и по обсуждать.
Итак! Имеем:
Arduino Pro Mini (на самом деле неважно какая) с програмированием в Arduino IDE 1.8.9 (в общем случае тоже неважно)
Raspberry Pi3 (так же неважно какая) с программированием на Python3 (на самом деле очень важно, потому что Python3 и все предыдущие версии отличаются крайне сильно.
Сразу же скажу, что если с arduino я знаком достаточно давно, то с raspberry и языком программирования Python3 знаком не сильно.
Задача: Отправить несколько байт с малинки на ардуину, в ответ получить несколько байт с ардуины обратно в малинку. Ради унификации, хотелось бы на ардуине использовать универсальны скетч из проекта ESPEasy https://www.letscontrolit.com/wiki/index.php?title=ProMiniExtender
Если внимательно глянуть, то в этом скетче ардуино по i2c принимается команда из 4-х байт. В ответ посылает 0-2 байта как результат.
Для начала, просто попробуем послать число в INT (2 байта). Теперь что получаю и с чем столкнулся в процессе отладки:
Послать Raspberry - > Arduino 2 байта достаточно просто:
На ардуино принимаем и отправляем обратно:
В итоге получается какая-то фигня.
С малинки улетает не 2 а 3 байта. 3-йбайт является повторением 2-го. Ладно. На ардуино принимает 3 байта, последний отбрасываем.
Отправляем обратно:
Wire.write(number);
(можно и разбив на 2 байта, без разницы)
или так:
Wire.write(number&0xFF);
Wire.write(number>>8);
Без разницы. На малинку прилетает ТОЛЬКО последний байт.
Я уже голову сломал.
Что многоуважаемый All может сказать на эту тему: Может у кого-нить уже есть достойная повторения реализация многобайтной передачи между этими двумя дейвайсами?