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

andy1989
Offline
Зарегистрирован: 12.09.2013

Доброй ночи, я пытаюсь реализовать следующую идею: передавать значения гироскопа (ADXL345) с передатчика (Arduino UNO) на приемник (Arduino UNO + Ethernet Shield) при помощи RF модуля (RF1212), соответственно используется последовательная передача данных. Проблема заключается в том что не получается корректно передать данные на приемник. Подскажите могу ли я использовать в моей ситуации библиотеку VirtualWire для составления структуры пакета, точнее будет ли она корректно работать с моими RF модулями (http://appconwireless.blogspot.ru/2013/01/ultra-low-power-consumption-solution.html) ?

maksim
Offline
Зарегистрирован: 12.02.2012

Нет не будет, эта библиотека для других целей.

andy1989
Offline
Зарегистрирован: 12.09.2013

Тогда что можите посоветовать для коректной отправки и приема данных?

Вот код приемника:

// Программный модуль для приема и хранения информации 
#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();
}

 

maksim
Offline
Зарегистрирован: 12.02.2012

Вы можете поискать по форуму как правильно передавать и принимать данные по сериал соединению.

Я бы сделал так:

  передатчик:

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().

andy1989
Offline
Зарегистрирован: 12.09.2013

Спасибо большое, на счет 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();
  }
}

 

maksim
Offline
Зарегистрирован: 12.02.2012

Можно, но в примерах выше он будет и так очичаться до тех пор пока не "встретит" идентификатор начала пакета D.

andy1989
Offline
Зарегистрирован: 12.09.2013

Спасибо за разъяснения))))

andy1989
Offline
Зарегистрирован: 12.09.2013

Попробовал вашу конструкцию, не получилось( На выходе из передатчика идут не читаемые символы.

Передатчик:

// Передача данных с гироскопа

#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);
}

 

maksim
Offline
Зарегистрирован: 12.02.2012

На каком выходе? И с чего вдруг они должны быть читаемыми? Они могут стать читаемыми если вы их соберете функцией IntRead() в числа и отправите в монитор кодами АСКИ.

andy1989
Offline
Зарегистрирован: 12.09.2013

Информация приходит с гироскопа на arduino с 4 и 5 входов, то есть мы ни как не сможем посмотреть какую информацию мы отправляем на приемник? Буду пробывать тогда копаться дальше)

andy1989
Offline
Зарегистрирован: 12.09.2013

Так же хотел спросить а почему в коде приемника 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];
}

 

maksim
Offline
Зарегистрирован: 12.02.2012

В общем не те вопросы вы задаете. Изучайте раздел Программирование вчастиноти Типы данных и описание класса Serial.

Вам пока не стоит вдаваться в эти подробности. Просто берете функции и пользуетесь.

Функция IntRead() читает только одну переменную типа int, состоящую из двух байт.

 

andy1989
Offline
Зарегистрирован: 12.09.2013

Передача данных работает и еще раз спасибо вам за это, но проблема появилась слейдущая что в один прекрасный момент должны придти примерно такие данные -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);
}

 

 

maksim
Offline
Зарегистрирован: 12.02.2012

Могу предположить что у вас переполняется буфер так как в приемнике сумарная задержка больше чем в передатчике. То есть вы отправляете данных больше чем можете прочитать.

Для чего это строка? 

delay(1000);  // пауза

уберите ее.

andy1989
Offline
Зарегистрирован: 12.09.2013

Спасибо эту строку уже нашел, вот только числа теперь начали прыгать в районе 256(

andy1989
Offline
Зарегистрирован: 12.09.2013

Причем числа передаются нормально, но какая та из координат без переодичности может стать числом от 254 до 256. Пробывал ставить задержку отправки на передатчике 6000 мс.

maksim
Offline
Зарегистрирован: 12.02.2012

Попробуйте в 63 строке увеличить задержку:

 delay(100);

 

andy1989
Offline
Зарегистрирован: 12.09.2013

Попробывал не помогает, еще убрал блок записи в файл:

 
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 участилось  

maksim
Offline
Зарегистрирован: 12.02.2012

А в каком диапазоне у вас меняются данные в переменных x, y, z ?

andy1989
Offline
Зарегистрирован: 12.09.2013

Я стараяюсь чтобы гироскоп был в не подвижном состоянии и данные от -1 до +1. Иногда при загрузке первых чисел он сразу выдает одно из чисел равным 256. 

maksim
Offline
Зарегистрирован: 12.02.2012

Не важно как вы стараетесь и что вы хотите, важно в каких пределах изменяются данные.

andy1989
Offline
Зарегистрирован: 12.09.2013

Если гироскоп находится в не подвижном состоянии данные изменяются от -2 до +2

maksim
Offline
Зарегистрирован: 12.02.2012

А если без если?

andy1989
Offline
Зарегистрирован: 12.09.2013

Извиняюсь я имел виду не гироскоп, а акселерометр))) Диапазан измерения у него до ±16g.

andy1989
Offline
Зарегистрирован: 12.09.2013

Уважаемый Максим а если сделать так чтобы приемник отсылал передатчику индификатор разрешающий передачу и только после этого передатчик начинал отсылать данные на приемник имеет ли такая идея право на существование?

andy1989
Offline
Зарегистрирован: 12.09.2013

Возможно ли связать две Arduino без радио модулей на прямую через RX и TX?

andy1989
Offline
Зарегистрирован: 12.09.2013

Соединил такая же картина(

andy1989
Offline
Зарегистрирован: 12.09.2013

При соединении напрямую работает как надо (код ниже), но этот код уже не работает при использовании 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];
}

 

maksim
Offline
Зарегистрирован: 12.02.2012

В общем вы так и не написали в каком диапазоне у вас изменяются значения в переменных 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() в вашем случае нужно с указанием базиса:

Serial.print(x, DEC);