Прошу помощи в реализации проекта.
- Войдите на сайт для отправки комментариев
Пт, 21/02/2014 - 18:23
Добрый день форумчане. Прошу помочь с реализацией проекта.
Итак. Есть Arduino Mega 2560, Arduino Uno, Ethernet Shield,Troyka Shield и датчик температуры DHT-11.
Идея заключается в следующем:
1) Arduino Mega 2560 и Arduino Uno соединить по I2C:

Скетчи для Master и Slave:
Для Master (Arduino Mega 2560):
#include <Wire.h> //подключаем библиотеку
#define ADDR 2 //адрес нужного нам Slave
void setup()
{
Wire.begin(); //включить i2c
}
void loop()// Главный цикл
{
Wire.beginTransmission(ADDR); //начало передачи, с адресом нужного нам Slave
Wire.write(111); //отправляем данные для выбраного Slave
Wire.endTransmission(); //конец передачи
delay(1000); //пауза
}
Для Slave (Arduino Uno):
#include <Wire.h>
#define ADDR 2 //адрес устройства
void setup()
{
Serial.begin(9600);//скорость обмена с компом
Wire.begin(ADDR); //определим как ведомый с указанным адресом
Wire.onReceive(receive_handler); //ждем данных от мастера, функция возвращает int число байт данных
}
void loop() {}
void receive_handler(int numbytes)
{
for (int i=0;i<numbytes;i++) //читаем весь пакет
{
Serial.print(Wire.read()); // принимаем значение и передаем компьютеру
}
Serial.println(' '); //перенос строки
}
2) На Arduino Uno с Troyka Shield подключим датчик DHT-11:
Скетч:
#include <dht.h>
int ledPin = 13;
// Создаем сенсор
DHT sensor = DHT();
void setup()
{
Serial.begin(9600);
// Подключаем сенсор к 0 аналоговому порту
sensor.attach(A0);
// Ждем готовность сенсора
delay(1000);
}
void loop()
{
// Проводим измерения
sensor.update();
switch (sensor.getLastError())
{
case DHT_ERROR_OK:
char msg[128];
// Если ошибок нет, то собираем данные
sprintf(msg, "Vlaznost = %d%% Temp = %dC",
sensor.getHumidityInt(), sensor.getTemperatureInt());
Serial.println(msg);
break;
case DHT_ERROR_START_FAILED_1:
Serial.println("Error: start failed (stage 1)");
break;
case DHT_ERROR_START_FAILED_2:
Serial.println("Error: start failed (stage 2)");
break;
}
delay(1000);
}
3) На Arduino Mega 2560 и Ethernet Shield запускаю сервер для своих нужд:
#include <SPI.h>
#include <Ethernet.h>
// MAC адрес нашего Ethernet шилда
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192, 168, 0, 244); // IP по которому мы будем обращаться к этой странице
EthernetServer server(80); // порт 80
void setup()
{
Ethernet.begin(mac, ip); // запускаем Ethernet шилд
server.begin(); // запуск web сервера
}
void loop()
{
EthernetClient client = server.available(); // опрашиваем канал в поисках клиента
if (client) { // если клиент найден
boolean currentLineIsBlank = true;
while (client.connected()) {
if (client.available()) { // если клиент доступен для чтения
char c = client.read(); // читаем 1 бит полученный от клиента
// <span style="font-size: 9pt; font-family: Consolas;">последняя строка запроса является пустой и заканчивается </span> \n
// реагировать на клиента только после полного прочтения
if (c == '\n' && currentLineIsBlank) {
// send a standard http response header
client.println("HTTP/1.1 200 OK");
client.println("Content-Type: text/html");
client.println("Connection: close");
client.println();
// send web page
client.println("<!DOCTYPE html>");
client.println("<html>");
client.println("<head>");
client.println("<title>Arduino Web Page</title>");
client.println("</head>");
client.println("<body>");
client.println("<h1>Привет от Arduino!</h1>");
client.println("<p>Эта страница с WEB сервера Arduino </p>");
client.println("</body>");
client.println("</html>");
break;
}
//каждая строка полученная от клиента заканчивается \r\n
if (c == '\n') {
// последний символ принятого запроса
// начало новой строки для чтения
currentLineIsBlank = true;
}
else if (c != '\r') {
// получение текстового символа от клиента
currentLineIsBlank = false;
}
} // end if (client.available())
} // end while (client.connected())
delay(1); // даем время для браузера получить данные
client.stop(); // закрываем соединение
}
}
Вопрос: Как организовать передачу показаний с датчика температуры по шине I2C на сервер?
P.S. Ногами не бейте, первый раз собираю проект на ардуино. Заранее благодарен.
Зачем это ? Цель какую преследуете ?
Задача от преподавателя. Получение информации с датчика температуры на сервер второй платы Arduino
В общем не понятно. Датчик подключен к какому контролеру ? Смысл в чем ? Объединть два контролера по i2c ?
Вы правы. Нужно подключить обе платы по I2C. Arduino Mega 2560 будет являться мастером.(на нем же и сервер),а на Arduino Uno подключен датчик температуры.(Uno - слейв) Показания датчика передать с Uno на Mega, и уже на Mega отправить их на сервер
Какой то странный канал между сервером и клиентом с датчиком. По моему скромному мнению в этом случае много правильнее использовать сериальный интерфейс. По крайней мере упростится задача и не нужно будет мучится с i2c.
т.е. SPI?
Нет, uart. Serial.print, Serial.read.
а примерчиком не поделитесь?
Нет компа под рукой, пишу с планшета. Контролеры нужно соединить двумя проводами tx -> rx, rx-> tx. Uno у вас каждую секунду выдает сообщение "Vlaznost...." принимайте это сообщение на меге и встраивайте его в html страничку. Поищите тут на форуме "как собрать стринг с ком порта".
Спасибо за совет,будем пробовать через serial.
это с Uno,а на Mega:
void setup() { Serial.begin(9600) } void loop() { while(Serial.read() > 0) { String ttydata = Serial.readString(); // ttyData - информация с серийного порта } }правильно понял?
Да, только вот не уверен, что readstring библиотечная функция. Помоему ее нужно написать.
вот примерчик нашел
int incomingByte = 0; // переменная для хранения полученного байта void setup() { Serial.begin(9600); // устанавливаем последовательное соединение } void loop() { if (Serial.available() > 0) { //если есть доступные данные // считываем байт incomingByte = Serial.read(); // отсылаем то, что получили Serial.print("I received: "); Serial.println(incomingByte, DEC); } }Нет это не правильно. Правильно так http://arduino.ru/forum/programmirovanie/kak-sobrat-string-ot-com-porta#comment-9805 . Только Строки 5,6,7 нужно выбросить, вместо них вставить break;. А принятое сообщение будет в inString. 7 строку поставьте перед первой. Получится кусок кода принимающий сообщение, которое нужно воткнуть в веб страничку.
Старый мой тест для Меги (основа взята с arduino.cc):
// Тестируем Iteaduino Mega 2560 на совместимость с классом SerialX // Тестируем void serialEvent2(). Работает!!! // Замкнул перемычкой пины RX2 и TX2. Работает!!! // !!! ACHTUNG !!! Есть небольшая задержка, первые несколько байт данных не передаются! // После включения SerialMonitor следует подождать несколько секунд. // !!! ACHTUNG !!! Работает даже без delay(50); String inputString = ""; // строка для накопления данных с UART2 boolean stringComplete = false; // флаг, строка пришла полностью, окончание строки по символу '\n' void setup() { // резервируем место под строку inputString.reserve(200); Serial.begin(9600); Serial2.begin(9600); } void loop() { static int inByte; // UART0 --> UART2 (передаем посимвольно) if (Serial.available()) { inByte = Serial.read(); Serial2.write(inByte); } //delay(50); // UART2 --> UART0 (передаем строкой) // выводим на монитор накопленную строку if (stringComplete) { Serial.print(inputString); // сбрасываем переменные для нового накопления строки inputString = ""; stringComplete = false; } //delay(50); } void serialEvent2() { static char inChar; while (Serial2.available()) { inChar = (char)Serial2.read(); // накапливаем строку из символов inputString += inChar; // получили окончание строки, можно обработать ее в главном цикле if (inChar == '\n') { stringComplete = true; } } }В примере используются оба варианта получения данных: посимвольный и строковый (класс String), кроме того, в варианте со String используется стандартный void serialEvent2() для отделения кода приема данных с UART2 от главного цикла программы. Для избежания багов при переполнении строки можно в serialEvent добавить код для проверки длины накопленной строки с максимальной зарезервированной под ее длиной.