Доброй ночи, я пытаюсь реализовать следующую идею: передавать значения гироскопа (ADXL345) с передатчика (Arduino UNO) на приемник (Arduino UNO + Ethernet Shield) при помощи RF модуля (RF1212), соответственно используется последовательная передача данных. Проблема заключается в том что не получается корректно передать данные на приемник. Подскажите могу ли я использовать в моей ситуации библиотеку VirtualWire для составления структуры пакета, точнее будет ли она корректно работать с моими RF модулями (RF1212) ?
А почему нет? Гироскоп просто отдает Вам данные. Как их передавать - без разницы. В чем конкретно заключается проблема? Данные приходят битыми или не приходят вообще?
Проблема заключается в следующем при соединении 2-х arduino напрямую (через RX и TX) работает как надо (код ниже), но этот код уже не работает при использовании rf модулей, принятые данные приемник отображает нулями: Код передатчика (через rx и tx): Код (C): // Передача данных с гироскопа #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): Код (C): // Программный модуль для приема и хранения информации #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]; }
Со следующем кодом передача работает через rf модули только появляется число 256 один, два раза в 10-15 показаниях с акселерометра. Хочу отметить что число 256 появляется только при передачи, на самом передатчике при просмотре работы акселерометра все работает как надо. Код передатчика (через rf): Код (C): // Передача данных с гироскопа #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): Код (C): // Передача данных с гироскопа #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); }
Попробуйте выбросить из прошивок все, что не относится к передаче данных и отладить только саму передачу. Потом можно добавлять кусочками и смотреть, в какой момент код начнет глючить.