Передача данных через RF модули
- Войдите на сайт для отправки комментариев
Чт, 12/09/2013 - 01:11
Доброй ночи, я пытаюсь реализовать следующую идею: передавать значения гироскопа (ADXL345) с передатчика (Arduino UNO) на приемник (Arduino UNO + Ethernet Shield) при помощи RF модуля (RF1212), соответственно используется последовательная передача данных. Проблема заключается в том что не получается корректно передать данные на приемник. Подскажите могу ли я использовать в моей ситуации библиотеку VirtualWire для составления структуры пакета, точнее будет ли она корректно работать с моими RF модулями (http://appconwireless.blogspot.ru/2013/01/ultra-low-power-consumption-solution.html) ?
Нет не будет, эта библиотека для других целей.
Тогда что можите посоветовать для коректной отправки и приема данных?
Вот код приемника:
// Программный модуль для приема и хранения информации #include <SPI.h> #include <SD.h> #include <Ethernet.h> int val=0; File myFile; // Инициализируем файл, где будем хранить данные int n=1; // Порядковй номер записи информации int x,y,z,a; // Enter a MAC address and IP address for your controller below. // Инициализируем MAC и IP адреса byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED}; IPAddress ip(192,168,0,177); EthernetServer server(80); // Наш сервер будет работать но 80 порту как обычный HTML void setup() { // Запускаем сервер Ethernet.begin(mac, ip); server.begin(); Serial.begin(9600); // Инициализируем порт ввода-вывода SD.begin(4); // Инициализируем карту памяти(SD) /* // Проверка работоспособности карты памяти if (!SD.begin(4)) Serial.println("initialization failed!"); else Serial.println("initialization done."); */ // Создаем файл с данными if(SD.exists("test.csv")) { SD.remove("test.csv"); // или удаляем существующий, если он есть на карте памяти } /* // Тестововая запись в файл данных myFile = SD.open("test.csv", FILE_WRITE); if (myFile) { Serial.print("Writing to test.csv..."); Serial.println("done."); } else { // if the file didn't open, print an error: Serial.println("error opening test.txt"); } myFile.close(); */ Serial.flush(); // Очищаем буффер порта ввода-вывода } void loop() { myFile = SD.open("test.csv",FILE_WRITE); // Открываем файл данных для записи if (Serial.available() > 0) { // Если в буффер порта ввода-вывода пришла информация // то считываем ее delay(1000); // пауза myFile.print("N - "); myFile.println(n); // Записываем в файл данных порядковый номер записи n++; // Увеличиваем порядковый номер на единицу //myFile.print("ID - "); //int a = Serial.parseInt(); // читаем первый байт - идентификатор гироскопа (A,B,C,...) //myFile.println(String(a)); // Записываем в файл x = Serial.read(); // Читаем угол X myFile.print(x); // Записываем в файл myFile.print(" --- "); y = Serial.read(); // Читаем угол Y myFile.print(y); // Записываем в файл myFile.print(" --- "); z = Serial.read(); // Читаем угол Z myFile.println(z); // Записываем в файл } // Serial.flush(); // Очищаем содержимого буффера порта ввода-вывода myFile.close(); // Закрываем файл данных // ДАЛЕЕ ГЕНЕРИРУЕМ HTML СТРАНИЦУ НА СЕРВЕРЕ EthernetClient client = server.available(); if (client) { // Serial.println("new client"); // an http request ends with a blank line boolean currentLineIsBlank = true; while (client.connected()) { if (client.available()) { char c = client.read(); // Serial.write(c); // if you've gotten to the end of the line (received a newline // character) and the line is blank, the http request has ended, // so you can send a reply 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("Connnection: close"); client.println(); client.println("<!DOCTYPE HTML>"); client.println("<html>"); client.println("<meta http-equiv=\"refresh\" content=\"5\">"); client.println("<title>Angle data</title>"); client.println("<style>table {width: 80%; margin: auto; text-align:center; align: center; background: maroon; color: navy; border-spacing: 1px; }"); client.println("td, th, tr { background: aqua; padding: 5px; margin: center; } </style>"); client.println("</head><body></br></br></br>"); client.println("<h1 align=\"center\">ANGLE DATA</h1>"); client.println("<h2><table bordercolor=\"black\">"); client.println("<tr><th></th><th>ANGLE - A</th><th>ANGLE - B</th><th>ANGLE - C</th></tr>"); client.println("<tr><td>X-"); client.println(n); client.println("</td><td>"); client.println(x); // Выводим угол x client.println("</td><td>"); client.println("</td><td>"); client.println("</td></tr>"); // блок 2 client.println("<tr><td>Y</td><td>"); client.println(y); // Выводим угол y client.println("</td><td>"); client.println("</td><td>"); client.println("</td></tr>"); //блок 3 client.println("<tr><td>Z</td><td>"); client.println(z); // Выводим угол z client.println("</td><td>"); client.println("</td><td>"); client.println("</td></tr>"); client.println("</table></h2>"); client.println("</body>"); client.println("</html>"); break; } if (c == '\n') { // you're starting a new line currentLineIsBlank = true; } else if (c != '\r') { // you've gotten a character on the current line currentLineIsBlank = false; } } } // give the web browser time to receive the data delay(500); // пауза // закрываем соединение client.stop(); } }и передатчика:
// Передача данных с гироскопа #include <Wire.h> #include <ADXL345.h> ADXL345 adxl; //variable adxl is an instance of the ADXL345 library int xs,ys,zs,i; int x,y,z; int id=199; void setup(){ Serial.begin(9600); adxl.powerOn(); // Начадьные Установки для акселлерометра ADXL345 //set activity/ inactivity thresholds (0-255) adxl.setActivityThreshold(75); //62.5mg per increment adxl.setInactivityThreshold(75); //62.5mg per increment adxl.setTimeInactivity(10); // how many seconds of no activity is inactive? //look of activity movement on this axes - 1 == on; 0 == off adxl.setActivityX(1); adxl.setActivityY(1); adxl.setActivityZ(1); //look of inactivity movement on this axes - 1 == on; 0 == off adxl.setInactivityX(1); adxl.setInactivityY(1); adxl.setInactivityZ(1); //look of tap movement on this axes - 1 == on; 0 == off adxl.setTapDetectionOnX(0); adxl.setTapDetectionOnY(0); adxl.setTapDetectionOnZ(1); //set values for what is a tap, and what is a double tap (0-255) adxl.setTapThreshold(50); //62.5mg per increment adxl.setTapDuration(15); //625μs per increment adxl.setDoubleTapLatency(80); //1.25ms per increment adxl.setDoubleTapWindow(200); //1.25ms per increment //set values for what is considered freefall (0-255) adxl.setFreeFallThreshold(7); //(5 - 9) recommended - 62.5mg per increment adxl.setFreeFallDuration(45); //(20 - 70) recommended - 5ms per increment //setting all interupts to take place on int pin 1 //I had issues with int pin 2, was unable to reset it adxl.setInterruptMapping( ADXL345_INT_SINGLE_TAP_BIT, ADXL345_INT1_PIN ); adxl.setInterruptMapping( ADXL345_INT_DOUBLE_TAP_BIT, ADXL345_INT1_PIN ); adxl.setInterruptMapping( ADXL345_INT_FREE_FALL_BIT, ADXL345_INT1_PIN ); adxl.setInterruptMapping( ADXL345_INT_ACTIVITY_BIT, ADXL345_INT1_PIN ); adxl.setInterruptMapping( ADXL345_INT_INACTIVITY_BIT, ADXL345_INT1_PIN ); //register interupt actions - 1 == on; 0 == off adxl.setInterrupt( ADXL345_INT_SINGLE_TAP_BIT, 1); adxl.setInterrupt( ADXL345_INT_DOUBLE_TAP_BIT, 1); adxl.setInterrupt( ADXL345_INT_FREE_FALL_BIT, 1); adxl.setInterrupt( ADXL345_INT_ACTIVITY_BIT, 1); adxl.setInterrupt( ADXL345_INT_INACTIVITY_BIT, 1); // Читаем данные с гироскопа adxl.readAccel(&x, &y, &z); //read the accelerometer values and store them in variables x,y,z // Обнуляем угол из среднего по 30 измерениям for (i=0;i<30;i++) { adxl.readAccel(&x, &y, &z); xs=xs+x; ys=ys+y; zs=zs+z; delay(500); // делаем паузу } // Рассчитываем усредненные данные объемного угла xs=xs/30; ys=ys/30; zs=zs/30; } void loop(){ // Читаем данные с акселлерометра adxl.readAccel(&x, &y, &z); //read the accelerometer values and store them in variables x,y,z // Вычитаем средние(начальные значения) x=x-xs; y=y-ys; z=z-zs; // Отправляем данные на базу(сервер) // Serial.println(id); // Это номер датчика // delay(100); // пауза Serial.print(x); Serial.print(" "); Serial.print(y); Serial.print(" "); Serial.println(z); delay(500); Serial.flush(); }Вы можете поискать по форуму как правильно передавать и принимать данные по сериал соединению.
Я бы сделал так:
передатчик:
void setup() { Serial.begin(9600); } void loop() { int x = analogRead(A0); int y = 12345; int z = 1000; Serial.print('D'); // идентификатор начала пакета IntPrint(x); IntPrint(y); IntPrint(z); delay(1000); } void IntPrint(int data) { byte *d = (byte*)&data; Serial.write(d, 2); }приемник:
int x = 0, y = 0, z = 0; void setup() { Serial.begin(9600); } void loop() { if(Serial.available()) { if(Serial.read() == 'D') { delay(10); x = IntRead(); y = IntRead(); z = IntRead(); } } } int IntRead() { byte d[2] = {Serial.read(), Serial.read()}; int *data = (int*)&d; return data[0]; }и почитайте что делает flush().
Спасибо большое, на счет flush как я почитал для очистки буфера можно использовать слейдущую конструкцию ? :
byte data[2]; // объявление массива на 3 переменных if(Serial.available() > 2) { for(byte i=0;i<2;i++)data[i]=Serial.read(); while(Serial.available()) // очищаем буфер { delay(5); Serial.read(); } }Можно, но в примерах выше он будет и так очичаться до тех пор пока не "встретит" идентификатор начала пакета D.
Спасибо за разъяснения))))
Попробовал вашу конструкцию, не получилось( На выходе из передатчика идут не читаемые символы.
Передатчик:
// Передача данных с гироскопа #include <Wire.h> #include <ADXL345.h> ADXL345 adxl; //variable adxl is an instance of the ADXL345 library int xs,ys,zs,i; int x,y,z; int id=199; void setup(){ Serial.begin(9600); adxl.powerOn(); // Начадьные Установки для акселлерометра ADXL345 //set activity/ inactivity thresholds (0-255) adxl.setActivityThreshold(75); //62.5mg per increment adxl.setInactivityThreshold(75); //62.5mg per increment adxl.setTimeInactivity(10); // how many seconds of no activity is inactive? //look of activity movement on this axes - 1 == on; 0 == off adxl.setActivityX(1); adxl.setActivityY(1); adxl.setActivityZ(1); //look of inactivity movement on this axes - 1 == on; 0 == off adxl.setInactivityX(1); adxl.setInactivityY(1); adxl.setInactivityZ(1); //look of tap movement on this axes - 1 == on; 0 == off adxl.setTapDetectionOnX(0); adxl.setTapDetectionOnY(0); adxl.setTapDetectionOnZ(1); //set values for what is a tap, and what is a double tap (0-255) adxl.setTapThreshold(50); //62.5mg per increment adxl.setTapDuration(15); //625μs per increment adxl.setDoubleTapLatency(80); //1.25ms per increment adxl.setDoubleTapWindow(200); //1.25ms per increment //set values for what is considered freefall (0-255) adxl.setFreeFallThreshold(7); //(5 - 9) recommended - 62.5mg per increment adxl.setFreeFallDuration(45); //(20 - 70) recommended - 5ms per increment //setting all interupts to take place on int pin 1 //I had issues with int pin 2, was unable to reset it adxl.setInterruptMapping( ADXL345_INT_SINGLE_TAP_BIT, ADXL345_INT1_PIN ); adxl.setInterruptMapping( ADXL345_INT_DOUBLE_TAP_BIT, ADXL345_INT1_PIN ); adxl.setInterruptMapping( ADXL345_INT_FREE_FALL_BIT, ADXL345_INT1_PIN ); adxl.setInterruptMapping( ADXL345_INT_ACTIVITY_BIT, ADXL345_INT1_PIN ); adxl.setInterruptMapping( ADXL345_INT_INACTIVITY_BIT, ADXL345_INT1_PIN ); //register interupt actions - 1 == on; 0 == off adxl.setInterrupt( ADXL345_INT_SINGLE_TAP_BIT, 1); adxl.setInterrupt( ADXL345_INT_DOUBLE_TAP_BIT, 1); adxl.setInterrupt( ADXL345_INT_FREE_FALL_BIT, 1); adxl.setInterrupt( ADXL345_INT_ACTIVITY_BIT, 1); adxl.setInterrupt( ADXL345_INT_INACTIVITY_BIT, 1); // Читаем данные с гироскопа adxl.readAccel(&x, &y, &z); //read the accelerometer values and store them in variables x,y,z // Обнуляем угол из среднего по 30 измерениям for (i=0;i<30;i++) { adxl.readAccel(&x, &y, &z); xs=xs+x; ys=ys+y; zs=zs+z; delay(500); // делаем паузу } // Рассчитываем усредненные данные объемного угла xs=xs/30; ys=ys/30; zs=zs/30; } void loop(){ // Читаем данные с акселлерометра adxl.readAccel(&x, &y, &z); //read the accelerometer values and store them in variables x,y,z // Вычитаем средние(начальные значения) x=x-xs; y=y-ys; z=z-zs; Serial.print('D'); // идентификатор начала пакета IntPrint(x); IntPrint(y); IntPrint(z); delay(1000); } void IntPrint(int data) { byte *d = (byte*)&data; Serial.write(d, 2); }На каком выходе? И с чего вдруг они должны быть читаемыми? Они могут стать читаемыми если вы их соберете функцией IntRead() в числа и отправите в монитор кодами АСКИ.
Информация приходит с гироскопа на arduino с 4 и 5 входов, то есть мы ни как не сможем посмотреть какую информацию мы отправляем на приемник? Буду пробывать тогда копаться дальше)
Так же хотел спросить а почему в коде приемника Serial.read() идет 2 раза а не 3? Ведь у нас массив состоит из 3 позиций.
Код приемника
int x = 0, y = 0, z = 0; void setup() { Serial.begin(9600); } void loop() { if(Serial.available()) { if(Serial.read() == 'D') { delay(10); x = IntRead(); y = IntRead(); z = IntRead(); } } } int IntRead() { byte d[2] = {Serial.read(), Serial.read()}; int *data = (int*)&d; return data[0]; }В общем не те вопросы вы задаете. Изучайте раздел Программирование вчастиноти Типы данных и описание класса Serial.
Вам пока не стоит вдаваться в эти подробности. Просто берете функции и пользуетесь.
Функция IntRead() читает только одну переменную типа int, состоящую из двух байт.
Передача данных работает и еще раз спасибо вам за это, но проблема появилась слейдущая что в один прекрасный момент должны придти примерно такие данные -2 1 0, а приходит все три числа по 17476 или одномиз чисел 17476. Вообщем это число начинает повторятся(
Код приемника:
// Программный модуль для приема и хранения информации #include <SPI.h> #include <SD.h> #include <Ethernet.h> int val=0; File myFile; // Инициализируем файл, где будем хранить данные int n=1; // Порядковй номер записи информации int x,y,z,a; // Enter a MAC address and IP address for your controller below. // Инициализируем MAC и IP адреса byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED}; IPAddress ip(192,168,0,177); EthernetServer server(80); // Наш сервер будет работать но 80 порту как обычный HTML void setup() { // Запускаем сервер Ethernet.begin(mac, ip); server.begin(); Serial.begin(9600); // Инициализируем порт ввода-вывода SD.begin(4); // Инициализируем карту памяти(SD) /* // Проверка работоспособности карты памяти if (!SD.begin(4)) Serial.println("initialization failed!"); else Serial.println("initialization done."); */ // Создаем файл с данными if(SD.exists("test.csv")) { SD.remove("test.csv"); // или удаляем существующий, если он есть на карте памяти } /* // Тестововая запись в файл данных myFile = SD.open("test.csv", FILE_WRITE); if (myFile) { Serial.print("Writing to test.csv..."); Serial.println("done."); } else { // if the file didn't open, print an error: Serial.println("error opening test.txt"); } myFile.close(); */ Serial.flush(); // Очищаем буффер порта ввода-вывода } void loop() { myFile = SD.open("test.csv",FILE_WRITE); // Открываем файл данных для записи if (Serial.available() > 0) { // Если в буффер порта ввода-вывода пришла информация // то считываем ее delay(1000); // пауза myFile.print("N - "); myFile.println(n); // Записываем в файл данных порядковый номер записи n++; // Увеличиваем порядковый номер на единицу //myFile.print("ID - "); //int a = Serial.parseInt(); // читаем первый байт - идентификатор гироскопа (A,B,C,...) //myFile.println(String(a)); // Записываем в файл if(Serial.read() == 'D') { delay(10); x = IntRead(); myFile.print(x); // Записываем в файл myFile.print(" --- "); y = IntRead(); myFile.print(y); // Записываем в файл myFile.print(" --- "); z = IntRead(); myFile.println(z); // Записываем в файл } } // Serial.flush(); // Очищаем содержимого буффера порта ввода-вывода myFile.close(); // Закрываем файл данных // ДАЛЕЕ ГЕНЕРИРУЕМ HTML СТРАНИЦУ НА СЕРВЕРЕ EthernetClient client = server.available(); if (client) { // Serial.println("new client"); // an http request ends with a blank line boolean currentLineIsBlank = true; while (client.connected()) { if (client.available()) { char c = client.read(); // Serial.write(c); // if you've gotten to the end of the line (received a newline // character) and the line is blank, the http request has ended, // so you can send a reply 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("Connnection: close"); client.println(); client.println("<!DOCTYPE HTML>"); client.println("<html>"); client.println("<meta http-equiv=\"refresh\" content=\"5\">"); client.println("<title>Angle data</title>"); client.println("<style>table {width: 80%; margin: auto; text-align:center; align: center; background: maroon; color: navy; border-spacing: 1px; }"); client.println("td, th, tr { background: aqua; padding: 5px; margin: center; } </style>"); client.println("</head><body></br></br></br>"); client.println("<h1 align=\"center\">ANGLE DATA</h1>"); client.println("<h2><table bordercolor=\"black\">"); client.println("<tr><th></th><th>ANGLE - A</th><th>ANGLE - B</th><th>ANGLE - C</th></tr>"); client.println("<tr><td>X-"); client.println(n); client.println("</td><td>"); client.println(x); // Выводим угол x client.println("</td><td>"); client.println("</td><td>"); client.println("</td></tr>"); // блок 2 client.println("<tr><td>Y</td><td>"); client.println(y); // Выводим угол y client.println("</td><td>"); client.println("</td><td>"); client.println("</td></tr>"); //блок 3 client.println("<tr><td>Z</td><td>"); client.println(z); // Выводим угол z client.println("</td><td>"); client.println("</td><td>"); client.println("</td></tr>"); client.println("</table></h2>"); client.println("</body>"); client.println("</html>"); break; } if (c == '\n') { // you're starting a new line currentLineIsBlank = true; } else if (c != '\r') { // you've gotten a character on the current line currentLineIsBlank = false; } } } // give the web browser time to receive the data delay(500); // пауза // закрываем соединение client.stop(); } } int IntRead() { byte d[2] = {Serial.read(), Serial.read()}; int *data = (int*)&d; return data[0]; }Код передатчика:
// Передача данных с гироскопа #include <Wire.h> #include <ADXL345.h> ADXL345 adxl; //variable adxl is an instance of the ADXL345 library int xs,ys,zs,i; int x,y,z; int id=199; void setup(){ Serial.begin(9600); adxl.powerOn(); // Начадьные Установки для акселлерометра ADXL345 //set activity/ inactivity thresholds (0-255) adxl.setActivityThreshold(75); //62.5mg per increment adxl.setInactivityThreshold(75); //62.5mg per increment adxl.setTimeInactivity(10); // how many seconds of no activity is inactive? //look of activity movement on this axes - 1 == on; 0 == off adxl.setActivityX(1); adxl.setActivityY(1); adxl.setActivityZ(1); //look of inactivity movement on this axes - 1 == on; 0 == off adxl.setInactivityX(1); adxl.setInactivityY(1); adxl.setInactivityZ(1); //look of tap movement on this axes - 1 == on; 0 == off adxl.setTapDetectionOnX(0); adxl.setTapDetectionOnY(0); adxl.setTapDetectionOnZ(1); //set values for what is a tap, and what is a double tap (0-255) adxl.setTapThreshold(50); //62.5mg per increment adxl.setTapDuration(15); //625μs per increment adxl.setDoubleTapLatency(80); //1.25ms per increment adxl.setDoubleTapWindow(200); //1.25ms per increment //set values for what is considered freefall (0-255) adxl.setFreeFallThreshold(7); //(5 - 9) recommended - 62.5mg per increment adxl.setFreeFallDuration(45); //(20 - 70) recommended - 5ms per increment //setting all interupts to take place on int pin 1 //I had issues with int pin 2, was unable to reset it adxl.setInterruptMapping( ADXL345_INT_SINGLE_TAP_BIT, ADXL345_INT1_PIN ); adxl.setInterruptMapping( ADXL345_INT_DOUBLE_TAP_BIT, ADXL345_INT1_PIN ); adxl.setInterruptMapping( ADXL345_INT_FREE_FALL_BIT, ADXL345_INT1_PIN ); adxl.setInterruptMapping( ADXL345_INT_ACTIVITY_BIT, ADXL345_INT1_PIN ); adxl.setInterruptMapping( ADXL345_INT_INACTIVITY_BIT, ADXL345_INT1_PIN ); //register interupt actions - 1 == on; 0 == off adxl.setInterrupt( ADXL345_INT_SINGLE_TAP_BIT, 1); adxl.setInterrupt( ADXL345_INT_DOUBLE_TAP_BIT, 1); adxl.setInterrupt( ADXL345_INT_FREE_FALL_BIT, 1); adxl.setInterrupt( ADXL345_INT_ACTIVITY_BIT, 1); adxl.setInterrupt( ADXL345_INT_INACTIVITY_BIT, 1); // Читаем данные с гироскопа adxl.readAccel(&x, &y, &z); //read the accelerometer values and store them in variables x,y,z // Обнуляем угол из среднего по 30 измерениям for (i=0;i<30;i++) { adxl.readAccel(&x, &y, &z); xs=xs+x; ys=ys+y; zs=zs+z; delay(500); // делаем паузу } // Рассчитываем усредненные данные объемного угла xs=xs/30; ys=ys/30; zs=zs/30; } void loop(){ // Читаем данные с акселлерометра adxl.readAccel(&x, &y, &z); //read the accelerometer values and store them in variables x,y,z // Вычитаем средние(начальные значения) x=x-xs; y=y-ys; z=z-zs; Serial.print('D'); // идентификатор начала пакета IntPrint(x); IntPrint(y); IntPrint(z); delay(1000); } void IntPrint(int data) { byte *d = (byte*)&data; Serial.write(d, 2); }Могу предположить что у вас переполняется буфер так как в приемнике сумарная задержка больше чем в передатчике. То есть вы отправляете данных больше чем можете прочитать.
Для чего это строка?
уберите ее.
Спасибо эту строку уже нашел, вот только числа теперь начали прыгать в районе 256(
Причем числа передаются нормально, но какая та из координат без переодичности может стать числом от 254 до 256. Пробывал ставить задержку отправки на передатчике 6000 мс.
Попробуйте в 63 строке увеличить задержку:
Попробывал не помогает, еще убрал блок записи в файл:
if(Serial.read() == 'D') { delay(100); x = IntRead(); //myFile.print(x); // Записываем в файл //myFile.print(" --- "); y = IntRead(); //myFile.print(y); // Записываем в файл //myFile.print(" --- "); z = IntRead(); //myFile.println(z); // Записываем в файл }После этого появление числа 256 участилось
А в каком диапазоне у вас меняются данные в переменных x, y, z ?
Я стараяюсь чтобы гироскоп был в не подвижном состоянии и данные от -1 до +1. Иногда при загрузке первых чисел он сразу выдает одно из чисел равным 256.
Не важно как вы стараетесь и что вы хотите, важно в каких пределах изменяются данные.
Если гироскоп находится в не подвижном состоянии данные изменяются от -2 до +2
А если без если?
Извиняюсь я имел виду не гироскоп, а акселерометр))) Диапазан измерения у него до ±16g.
Уважаемый Максим а если сделать так чтобы приемник отсылал передатчику индификатор разрешающий передачу и только после этого передатчик начинал отсылать данные на приемник имеет ли такая идея право на существование?
Возможно ли связать две Arduino без радио модулей на прямую через RX и TX?
Соединил такая же картина(
При соединении напрямую работает как надо (код ниже), но этот код уже не работает при использовании rf модулей, принятые данные приемник отображает нулями:
Код передатчика (через rx и tx):
// Передача данных с гироскопа #include <Wire.h> #include <ADXL345.h> ADXL345 adxl; //variable adxl is an instance of the ADXL345 library int xs,ys,zs,i; int x,y,z; int id=199; void setup(){ Serial.begin(9600); adxl.powerOn(); // Начадьные Установки для акселлерометра ADXL345 //set activity/ inactivity thresholds (0-255) adxl.setActivityThreshold(75); //62.5mg per increment adxl.setInactivityThreshold(75); //62.5mg per increment adxl.setTimeInactivity(10); // how many seconds of no activity is inactive? //look of activity movement on this axes - 1 == on; 0 == off adxl.setActivityX(1); adxl.setActivityY(1); adxl.setActivityZ(1); //look of inactivity movement on this axes - 1 == on; 0 == off adxl.setInactivityX(1); adxl.setInactivityY(1); adxl.setInactivityZ(1); //look of tap movement on this axes - 1 == on; 0 == off adxl.setTapDetectionOnX(0); adxl.setTapDetectionOnY(0); adxl.setTapDetectionOnZ(1); //set values for what is a tap, and what is a double tap (0-255) adxl.setTapThreshold(50); //62.5mg per increment adxl.setTapDuration(15); //625?s per increment adxl.setDoubleTapLatency(80); //1.25ms per increment adxl.setDoubleTapWindow(200); //1.25ms per increment //set values for what is considered freefall (0-255) adxl.setFreeFallThreshold(7); //(5 - 9) recommended - 62.5mg per increment adxl.setFreeFallDuration(45); //(20 - 70) recommended - 5ms per increment //setting all interupts to take place on int pin 1 //I had issues with int pin 2, was unable to reset it adxl.setInterruptMapping( ADXL345_INT_SINGLE_TAP_BIT, ADXL345_INT1_PIN ); adxl.setInterruptMapping( ADXL345_INT_DOUBLE_TAP_BIT, ADXL345_INT1_PIN ); adxl.setInterruptMapping( ADXL345_INT_FREE_FALL_BIT, ADXL345_INT1_PIN ); adxl.setInterruptMapping( ADXL345_INT_ACTIVITY_BIT, ADXL345_INT1_PIN ); adxl.setInterruptMapping( ADXL345_INT_INACTIVITY_BIT, ADXL345_INT1_PIN ); //register interupt actions - 1 == on; 0 == off adxl.setInterrupt( ADXL345_INT_SINGLE_TAP_BIT, 1); adxl.setInterrupt( ADXL345_INT_DOUBLE_TAP_BIT, 1); adxl.setInterrupt( ADXL345_INT_FREE_FALL_BIT, 1); adxl.setInterrupt( ADXL345_INT_ACTIVITY_BIT, 1); adxl.setInterrupt( ADXL345_INT_INACTIVITY_BIT, 1); // Читаем данные с гироскопа adxl.readAccel(&x, &y, &z); //read the accelerometer values and store them in variables x,y,z // Обнуляем угол из среднего по 30 измерениям for (i=0;i<30;i++) { adxl.readAccel(&x, &y, &z); xs=xs+x; ys=ys+y; zs=zs+z; delay(500); // делаем паузу } // Рассчитываем усредненные данные объемного угла xs=xs/30; ys=ys/30; zs=zs/30; } void loop(){ if (Serial.available()) { if(Serial.read() == 'A') { // Читаем данные с акселлерометра adxl.readAccel(&x, &y, &z); //read the accelerometer values and store them in variables x,y,z // Вычитаем средние(начальные значения) x=x-xs; y=y-ys; z=z-zs; Serial.print('D'); // идентификатор начала пакета IntPrint(x); IntPrint(y); IntPrint(z); delay(500); } } } void IntPrint(int data) { byte *d = (byte*)&data; Serial.write(d, 2); }Код приемника (через rx и tx):
// Программный модуль для приема и хранения информации #include <SPI.h> #include <SD.h> #include <Ethernet.h> int val=0; File myFile; // Инициализируем файл, где будем хранить данные int n=1; // Порядковй номер записи информации int x,y,z,a; // Enter a MAC address and IP address for your controller below. // Инициализируем MAC и IP адреса byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED}; IPAddress ip(192,168,0,177); EthernetServer server(80); // Наш сервер будет работать но 80 порту как обычный HTML void setup() { // Запускаем сервер Ethernet.begin(mac, ip); server.begin(); Serial.begin(9600); // Инициализируем порт ввода-вывода SD.begin(4); // Инициализируем карту памяти(SD) /* // Проверка работоспособности карты памяти if (!SD.begin(4)) Serial.println("initialization failed!"); else Serial.println("initialization done."); */ // Создаем файл с данными if(SD.exists("test.csv")) { SD.remove("test.csv"); // или удаляем существующий, если он есть на карте памяти } /* // Тестововая запись в файл данных myFile = SD.open("test.csv", FILE_WRITE); if (myFile) { Serial.print("Writing to test.csv..."); Serial.println("done."); } else { // if the file didn't open, print an error: Serial.println("error opening test.txt"); } myFile.close(); */ Serial.flush(); // Очищаем буффер порта ввода-вывода } void loop() { Serial.print('A'); delay(500); myFile = SD.open("test.csv",FILE_WRITE); // Открываем файл данных для записи if (Serial.available() > 0) { // Если в буффер порта ввода-вывода пришла информация // то считываем ее myFile.print("N - "); myFile.println(n); // Записываем в файл данных порядковый номер записи n++; // Увеличиваем порядковый номер на единицу //myFile.print("ID - "); //int a = Serial.parseInt(); // читаем первый байт - идентификатор гироскопа (A,B,C,...) //myFile.println(String(a)); // Записываем в файл if(Serial.read() == 'D') { delay(10); x = IntRead(); myFile.print(x); // Записываем в файл myFile.print(" --- "); y = IntRead(); myFile.print(y); // Записываем в файл myFile.print(" --- "); z = IntRead(); myFile.println(z); // Записываем в файл } } // Serial.flush(); // Очищаем содержимого буффера порта ввода-вывода myFile.close(); // Закрываем файл данных // ДАЛЕЕ ГЕНЕРИРУЕМ HTML СТРАНИЦУ НА СЕРВЕРЕ EthernetClient client = server.available(); if (client) { // Serial.println("new client"); // an http request ends with a blank line boolean currentLineIsBlank = true; while (client.connected()) { if (client.available()) { char c = client.read(); // Serial.write(c); // if you've gotten to the end of the line (received a newline // character) and the line is blank, the http request has ended, // so you can send a reply 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("Connnection: close"); client.println(); client.println("<!DOCTYPE HTML>"); client.println("<html>"); client.println("<meta http-equiv=\"refresh\" content=\"5\">"); client.println("<title>Angle data</title>"); client.println("<style>table {width: 80%; margin: auto; text-align:center; align: center; background: maroon; color: navy; border-spacing: 1px; }"); client.println("td, th, tr { background: aqua; padding: 5px; margin: center; } </style>"); client.println("</head><body></br></br></br>"); client.println("<h1 align=\"center\">ANGLE DATA</h1>"); client.println("<h2><table bordercolor=\"black\">"); client.println("<tr><th></th><th>ANGLE - A</th><th>ANGLE - B</th><th>ANGLE - C</th></tr>"); client.println("<tr><td>X-"); client.println(n); client.println("</td><td>"); client.println(x); // Выводим угол x client.println("</td><td>"); client.println("</td><td>"); client.println("</td></tr>"); // блок 2 client.println("<tr><td>Y</td><td>"); client.println(y); // Выводим угол y client.println("</td><td>"); client.println("</td><td>"); client.println("</td></tr>"); //блок 3 client.println("<tr><td>Z</td><td>"); client.println(z); // Выводим угол z client.println("</td><td>"); client.println("</td><td>"); client.println("</td></tr>"); client.println("</table></h2>"); client.println("</body>"); client.println("</html>"); break; } if (c == '\n') { // you're starting a new line currentLineIsBlank = true; } else if (c != '\r') { // you've gotten a character on the current line currentLineIsBlank = false; } } } // give the web browser time to receive the data // пауза // закрываем соединение client.stop(); } delay(7500); } int IntRead() { byte d[2] = {Serial.read(), Serial.read()}; int *data = (int*)&d; return data[0]; }Со слейдущем кодом передача работает только появляется число 256 один, два раза в 10-15 показаниях с акселерометра. Хочу отметить что число 256 появляется только при перидачи, на самом передатчике при просмотре работы акселерометра все работает как надо.
Код передатчика (через rf):
// Передача данных с гироскопа #include <Wire.h> #include <ADXL345.h> ADXL345 adxl; //variable adxl is an instance of the ADXL345 library int xs,ys,zs,i; int x,y,z; int id=199; void setup(){ Serial.begin(9600); adxl.powerOn(); // Начадьные Установки для акселлерометра ADXL345 //set activity/ inactivity thresholds (0-255) adxl.setActivityThreshold(75); //62.5mg per increment adxl.setInactivityThreshold(75); //62.5mg per increment adxl.setTimeInactivity(10); // how many seconds of no activity is inactive? //look of activity movement on this axes - 1 == on; 0 == off adxl.setActivityX(1); adxl.setActivityY(1); adxl.setActivityZ(1); //look of inactivity movement on this axes - 1 == on; 0 == off adxl.setInactivityX(1); adxl.setInactivityY(1); adxl.setInactivityZ(1); //look of tap movement on this axes - 1 == on; 0 == off adxl.setTapDetectionOnX(0); adxl.setTapDetectionOnY(0); adxl.setTapDetectionOnZ(1); //set values for what is a tap, and what is a double tap (0-255) adxl.setTapThreshold(50); //62.5mg per increment adxl.setTapDuration(15); //625?s per increment adxl.setDoubleTapLatency(80); //1.25ms per increment adxl.setDoubleTapWindow(200); //1.25ms per increment //set values for what is considered freefall (0-255) adxl.setFreeFallThreshold(7); //(5 - 9) recommended - 62.5mg per increment adxl.setFreeFallDuration(45); //(20 - 70) recommended - 5ms per increment //setting all interupts to take place on int pin 1 //I had issues with int pin 2, was unable to reset it adxl.setInterruptMapping( ADXL345_INT_SINGLE_TAP_BIT, ADXL345_INT1_PIN ); adxl.setInterruptMapping( ADXL345_INT_DOUBLE_TAP_BIT, ADXL345_INT1_PIN ); adxl.setInterruptMapping( ADXL345_INT_FREE_FALL_BIT, ADXL345_INT1_PIN ); adxl.setInterruptMapping( ADXL345_INT_ACTIVITY_BIT, ADXL345_INT1_PIN ); adxl.setInterruptMapping( ADXL345_INT_INACTIVITY_BIT, ADXL345_INT1_PIN ); //register interupt actions - 1 == on; 0 == off adxl.setInterrupt( ADXL345_INT_SINGLE_TAP_BIT, 1); adxl.setInterrupt( ADXL345_INT_DOUBLE_TAP_BIT, 1); adxl.setInterrupt( ADXL345_INT_FREE_FALL_BIT, 1); adxl.setInterrupt( ADXL345_INT_ACTIVITY_BIT, 1); adxl.setInterrupt( ADXL345_INT_INACTIVITY_BIT, 1); // Читаем данные с гироскопа adxl.readAccel(&x, &y, &z); //read the accelerometer values and store them in variables x,y,z // Обнуляем угол из среднего по 30 измерениям for (i=0;i<30;i++) { adxl.readAccel(&x, &y, &z); xs=xs+x; ys=ys+y; zs=zs+z; delay(500); // делаем паузу } // Рассчитываем усредненные данные объемного угла xs=xs/30; ys=ys/30; zs=zs/30; } void loop(){ // Читаем данные с акселлерометра adxl.readAccel(&x, &y, &z); //read the accelerometer values and store them in variables x,y,z // Вычитаем средние(начальные значения) x=x-xs; y=y-ys; z=z-zs; Serial.print('D'); // идентификатор начала пакета IntPrint(x); IntPrint(y); IntPrint(z); delay(6000); } void IntPrint(int data) { byte *d = (byte*)&data; Serial.write(d, 2); }Код приемника (через rf):
// Программный модуль для приема и хранения информации #include <SPI.h> #include <SD.h> #include <Ethernet.h> int val=0; File myFile; // Инициализируем файл, где будем хранить данные int n=1; // Порядковй номер записи информации int x,y,z,a; // Enter a MAC address and IP address for your controller below. // Инициализируем MAC и IP адреса byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED}; IPAddress ip(192,168,0,177); EthernetServer server(80); // Наш сервер будет работать но 80 порту как обычный HTML void setup() { // Запускаем сервер Ethernet.begin(mac, ip); server.begin(); Serial.begin(9600); // Инициализируем порт ввода-вывода SD.begin(4); // Инициализируем карту памяти(SD) /* // Проверка работоспособности карты памяти if (!SD.begin(4)) Serial.println("initialization failed!"); else Serial.println("initialization done."); */ // Создаем файл с данными if(SD.exists("test.csv")) { SD.remove("test.csv"); // или удаляем существующий, если он есть на карте памяти } /* // Тестововая запись в файл данных myFile = SD.open("test.csv", FILE_WRITE); if (myFile) { Serial.print("Writing to test.csv..."); Serial.println("done."); } else { // if the file didn't open, print an error: Serial.println("error opening test.txt"); } myFile.close(); */ Serial.flush(); // Очищаем буффер порта ввода-вывода } void loop() { myFile = SD.open("test.csv",FILE_WRITE); // Открываем файл данных для записи if (Serial.available() > 0) { // Если в буффер порта ввода-вывода пришла информация // то считываем ее //delay(1000); // пауза myFile.print("N - "); myFile.println(n); // Записываем в файл данных порядковый номер записи n++; // Увеличиваем порядковый номер на единицу //myFile.print("ID - "); //int a = Serial.parseInt(); // читаем первый байт - идентификатор гироскопа (A,B,C,...) //myFile.println(String(a)); // Записываем в файл if(Serial.read() == 'D') { delay(100); x = IntRead(); myFile.print(x); // Записываем в файл myFile.print(" --- "); y = IntRead(); myFile.print(y); // Записываем в файл myFile.print(" --- "); z = IntRead(); myFile.println(z); // Записываем в файл } } // Serial.flush(); // Очищаем содержимого буффера порта ввода-вывода myFile.close(); // Закрываем файл данных // ДАЛЕЕ ГЕНЕРИРУЕМ HTML СТРАНИЦУ НА СЕРВЕРЕ EthernetClient client = server.available(); if (client) { // Serial.println("new client"); // an http request ends with a blank line boolean currentLineIsBlank = true; while (client.connected()) { if (client.available()) { char c = client.read(); // Serial.write(c); // if you've gotten to the end of the line (received a newline // character) and the line is blank, the http request has ended, // so you can send a reply 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("Connnection: close"); client.println(); client.println("<!DOCTYPE HTML>"); client.println("<html>"); client.println("<meta http-equiv=\"refresh\" content=\"5\">"); client.println("<title>Angle data</title>"); client.println("<style>table {width: 80%; margin: auto; text-align:center; align: center; background: maroon; color: navy; border-spacing: 1px; }"); client.println("td, th, tr { background: aqua; padding: 5px; margin: center; } </style>"); client.println("</head><body></br></br></br>"); client.println("<h1 align=\"center\">ANGLE DATA</h1>"); client.println("<h2><table bordercolor=\"black\">"); client.println("<tr><th></th><th>ANGLE - A</th><th>ANGLE - B</th><th>ANGLE - C</th></tr>"); client.println("<tr><td>X-"); client.println(n); client.println("</td><td>"); client.println(x); // Выводим угол x client.println("</td><td>"); client.println("</td><td>"); client.println("</td></tr>"); // блок 2 client.println("<tr><td>Y</td><td>"); client.println(y); // Выводим угол y client.println("</td><td>"); client.println("</td><td>"); client.println("</td></tr>"); //блок 3 client.println("<tr><td>Z</td><td>"); client.println(z); // Выводим угол z client.println("</td><td>"); client.println("</td><td>"); client.println("</td></tr>"); client.println("</table></h2>"); client.println("</body>"); client.println("</html>"); break; } if (c == '\n') { // you're starting a new line currentLineIsBlank = true; } else if (c != '\r') { // you've gotten a character on the current line currentLineIsBlank = false; } } } // give the web browser time to receive the data delay(500); // пауза // закрываем соединение client.stop(); } } int IntRead() { byte d[2] = {Serial.read(), Serial.read()}; int *data = (int*)&d; return data[0]; }В общем вы так и не написали в каком диапазоне у вас изменяются значения в переменных x, y, z, поэтому если их значения колеблятся в пределах от -128 до 127, то обьявите их как char и передавайте/принимайте каждую переменну по одному байту.
передатчик:
void setup() { Serial.begin(9600); } void loop() { char x = -5; char y = 123; char z = 10; Serial.print('D'); // идентификатор начала пакета Serial.write(x); Serial.write(y); Serial.write(z); delay(1000); }приемник:
char x = 0, y = 0, z = 0; void setup() { Serial.begin(9600); } void loop() { if(Serial.available()) { if(Serial.read() == 'D') { delay(10); x = Serial.read(); y = Serial.read(); z = Serial.read(); } } }И учтите, что выводить переменные типа char через print() в вашем случае нужно с указанием базиса: