Завязал Arduino Uno с Raspberry Pi v.2 по i2c, ардуино (slave),малина (master). На ардуино подключены два аналоговых датчика (датчик газа и датчик пламени), вопрос состоит в том, что нужно внести в код pythona чтобы он мог распознавать информацию отосланной ардуинкой. Думал отправлять с ардуино массив целочисленных (int) - но при компиляции выдает ошибку, можно только отсылать массив байтов (byte), но так как у них ограничение до 255, а датчики конечный свои результат выдает и свыше 1000. Просто особых навыков программирования на питоне не имею, старался гуглить больше, но мозгов пока хватило только на это. Может кто поможет? Предоставляю скет ниже : Код (C): #include <Wire.h> //библиотека i2c #define SLAVE_ADDRESS 0x04 // ардуино объявлена слейвом int gas = 0; // переменная газового датчика int flame = 0; // переменная датчика пламени int number = 0; // переменная void setup() { Serial.begin(9600); //Set serial baud rate to 9600 bps Wire.begin(SLAVE_ADDRESS); Wire.onReceive(receiveData); Wire.onRequest (sendData); Serial.println("Ready!"); } void loop() { delay(1000); } void receiveData(int byteCount) { while(Wire.available()) { number = Wire.read(); } } void sendData() { gas=analogRead(0); flame=analogRead(1); Serial.print("Gas in air: "); Serial.println(gas,DEC); Serial.print("Flame in air: "); Serial.println(flame,DEC); Wire.write(gas); delay(100); Wire.write(flame); } И код на Python-e (это уже скрипт для Малинки) Код (C): import smbus import time bus = smbus.SMBus(1) address = 0x04 def writeNumber(value): bus.write_byte(address, value) return -1 def readGas(): gas = bus.read_byte(address) return gas time.sleep(0.1) def readFlame(): flame = bus.read_byte(address) return flame while True: var = input("Enter number: ") if not var: continue writeNumber(var) # sleep one second time.sleep(1) gas = readGas() flame = readFlame() print "Gas in the air: ", gas print print "Flame: ", flame print
Направлене мысли совершенно правильное. Вам нужно лишь побить длинные int'ы на байты. Что-то вроде: Код (C): void sendData() { gas=analogRead(A0); flame=analogRead(A1); Wire.write(gas >> 8); // отправляем старший байт Wire.write(gas & 0xff); // отправляем младший delay(100); Wire.write(flame >> 8); // отправляем старший байт Wire.write(flame & 0xff); // отправляем младший } на малине: Код (Python): def readGas(): gas = (bus.read_byte(address) << 8) | bus.read_byte(address) return gas И да, про I2C: вы точно не забыли решить проблему разницы уровней? На Arduino 5 В, а на GPIO Raspberry 3,3 В. Если на Raspberry прилетит 5 В с Arduino, ей это вряд ли понравится.
Мне тоже советовали эту методику решения проблемы, просто не мог представить это в виде кусочка кода, не понимал логику функций библиотеки smbus на малинке Благодарю вас, а насчет разницы логики, то это не проблематична, в том случае, если Малина - мастер, а ардуино - слэйв (как в моем случае), так как ардуино не имеет никаких подтягивающих резисторов, а малинка на p1 имеет на 1кОм (+3.3в). З.Ы Кстати, хотел поинтересоваться, вы это написали с помощью какой нибудь справочной информации, или по собственному опыту? а то бы я не прочь почитать материальчик если он есть, конечно. Update: Я хочу обучить малинку, чтобы она принимала сигналы "аналоговые" от ардуинки, несящие в себе результаты показаний датчиков, и в последующем ее внесение в базу Mysql, которая уже стоит на Малинке, поднят веб-сервер, и поддержка пхп присутствует. Проблема в том, что как можно подккоректировать функции библиотеки MySQLdb, так чтобы вносились (обновлялись) и результаты показаний определенного датчика и время его фиксации. А в web-морде я уже буду их "выдергивать" в веб-интерфейс, что конечно не составит особого труда. Кто хорошо разбирается в Питоне, оссобенно в его библиотеке MySQLdb? Будьте добры, помогите! База: Data ; Таблицы: Gas и Flame; и в каждой таблице два столбца - value и data. Код (C): #!/usr/bin/python # -*- coding: utf-8 import smbus import time import datetime import MySQLdb import cgi bus = smbus.SMBus(1) address = 0x04 def writeNumber(value): bus.write_byte(address, value) return -1 def readGas(): gas = (bus.read_byte(address) << 8) | bus.read_byte(address) return gas time.sleep(0.1) def readFlame(): flame = (bus.read_byte(address) << 8 | bus.read_byte(address) return flame while True: var = input("Enter number: ") if not var: continue writeNumber(var) # sleep one second time.sleep(1) gas = readGas() flame = readFlame() def mysqlConnect(): db = MySQLdb.connect(host="localhost", user="pi", passwd="*****", db="Data", charset='utf8') cur = db.cursor() cur.execute('SET NAMES `utf8`') data = {}; data['gas_value'] = cgi.escape (gas, True); data['flame_value'] = cgi.escape (flame, True); cur.execute =("""INSERT INTO gas('gas_value') VALUES); cur.execute =("""INSERT INTO flame('gas_value') VALUES); cur.close() db.close()
всем привет! я застрял на более низшем уровне и поэтому прошу помощи! идея примерна та же: из формы ПХП передавать ПИТОНУ данные, а Питоновый скрипт уже связывается с ардуиной по i2c. Через IDLE все работает, а если запускать через браузер, то не работает. И выполнение скрипта останавливается на строчке bus = smbus.SMBus(1) так же могу сказать, что не работает в браузере такая строчка var = input("Enter number: "). INPUT игнорится мне кажется что проблемы где-то рядом....
Доброго времени суток All! Подниму тему, потому как внятного результата в экспериментах получить не удалось. Проблема в том, что с малинку в ардуино я могу отправить несколько байт и там их получить. Но вот отправляя в ответ с ардуины в малинку несколько байт, на малинке получаю только последний байт. Причин пока понять не могу. Вот скетч на ардуине: Код (C++): #include <Wire.h> #define SLAVE_ADDRESS 0x04 int number = 0; int state = 0; byte dat[2]; byte num=0; byte num1=0; byte num2=0; void setup() { pinMode(13, OUTPUT); Serial.begin(19200); // start serial for output // initialize i2c as slave Wire.begin(SLAVE_ADDRESS); // define callbacks for i2c communication Wire.onReceive(receiveData); Wire.onRequest(sendData); Serial.println("Ready 555!"); } void loop() { delay(100); if( state==1 ) { Serial.println( "--------------------" ); state=0; } } // callback for received data void receiveData(int byteCount){ while(int n=Wire.available()) { number = Wire.read(); if( num==0 ) { num1=number; num=1; } else if( num==1 ) { num2=number; num=0; number=num1 + (num2<<8); } else num=0; } } // callback for sending data void sendData(){ Serial.println(number); Wire.write(number); } Вот код на малинке в питон3 Код (Python): #!/usr/bin/python3 import smbus import time # for RPI version 1, use "bus = smbus.SMBus(0)" bus = smbus.SMBus(1) # This is the address we setup in the Arduino Program address = 0x04 def writeNumber(value): bus.write_byte(address, int(value)&0xFF) bus.write_byte(address, int(value)>>8) # bus.write_byte(address, value.to_byte(2, byteorde='big')) # Рабочий вариант # bus.write_byte_data(address, 0, ord(value)) return -1 def readNumber(): # num = bus.read_byte(address) num = (bus.read_byte(address) << 8) | bus.read_byte(address) return num while True: var = input("Enter 1 – 9: ") if not var: continue writeNumber(var) print( "RPI: Привет Arduino, Я послал тебе ", var) # sleep one second time.sleep(1) number = readNumber() print( "Arduino: Привет RPI, Я ответил тебе 1: ", number ) number = readNumber() print( "Arduino: Привет RPI, Я ответил тебе 2:", number ) number=0 print В этом коде с малинки отправляется введённое число, в ответ ардуина отправляет это число обратно. Непоняток две: На ардуину приходит 3 байта. 3-й байт повторяет 2-й На малинку возвращается только последний байт.