Передача данных через RF модули

Тема в разделе "Arduino & Shields", создана пользователем andy1989, 12 сен 2013.

  1. andy1989

    andy1989 Нуб

    Доброй ночи, я пытаюсь реализовать следующую идею: передавать значения гироскопа (ADXL345) с передатчика (Arduino UNO) на приемник (Arduino UNO + Ethernet Shield) при помощи RF модуля (RF1212), соответственно используется последовательная передача данных. Проблема заключается в том что не получается корректно передать данные на приемник. Подскажите могу ли я использовать в моей ситуации библиотеку VirtualWire для составления структуры пакета, точнее будет ли она корректно работать с моими RF модулями (RF1212) ?
     
  2. Megakoteyka

    Megakoteyka Оракул Модератор

    А почему нет? Гироскоп просто отдает Вам данные. Как их передавать - без разницы.
    В чем конкретно заключается проблема? Данные приходят битыми или не приходят вообще?
     
  3. andy1989

    andy1989 Нуб

    Проблема заключается в следующем при соединении 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];
    }
     
  4. andy1989

    andy1989 Нуб

    Со следующем кодом передача работает через 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);
    }
     
  5. Megakoteyka

    Megakoteyka Оракул Модератор

    Попробуйте выбросить из прошивок все, что не относится к передаче данных и отладить только саму передачу.
    Потом можно добавлять кусочками и смотреть, в какой момент код начнет глючить.