Помогите разобраться с радиомодулем 433Гц

imv14
Offline
Зарегистрирован: 02.04.2014

Сделал небольшую метеостанцию: bmp085, dht, ds1307. Вывожу все это на диодные цифры.Вот код: 

#include "Wire.h"
#include "LedControl.h"
#include "DHT.h"
#include <BMP085.h>
#define DS1307_I2C_ADDRESS 0x68

DHT dht;

BMP085 dps = BMP085(); 
long Temperature = 0, Pressure = 0, Altitude = 0;

int T,D,H;

LedControl lc=LedControl(12,11,10,1); //(dataPin-1,clockPin-13,csPin-12,кол-во микросхем)
 
byte decToBcd(byte val)
{
  return ( (val/10*16) + (val%10) );
}
byte bcdToDec(byte val)
{
  return ( (val/16*10) + (val%16) );
}

void setDateDs1307(byte second,        // 0-59
                   byte minute,        // 0-59
	           byte hour)        // 0-99
{
  Wire.beginTransmission(DS1307_I2C_ADDRESS);
  Wire.write(0);
  Wire.write(decToBcd(second));   
  Wire.write(decToBcd(minute));
  Wire.write(decToBcd(hour));    
  Wire.endTransmission();
}
void getDateDs1307(byte *second,
	           byte *minute,
	           byte *hour)
{
  Wire.beginTransmission(DS1307_I2C_ADDRESS);
  Wire.write(0);
  Wire.endTransmission();
  Wire.requestFrom(DS1307_I2C_ADDRESS, 3);
	 *second     = bcdToDec(Wire.read());
	 *minute     = bcdToDec(Wire.read());
	 *hour       = bcdToDec(Wire.read()); 
}
void setup()
{
  dht.setup(2); // data pin 2
  
  byte second, minute, hour;
  Wire.begin();
  dps.init();      //BMP085   
  
  lc.shutdown(0,false);
  lc.setIntensity(0,8);
  lc.clearDisplay(0);
  
  pinMode(3, OUTPUT); 
  digitalWrite(3, HIGH);
  
  Serial.begin(9600);
// Установка времени
//    second = 00;
//    minute = 28;
//    hour = 12;
//    setDateDs1307(second, minute, hour);
}
void loop()
{
  delay(dht.getMinimumSamplingPeriod());
  int humidity = dht.getHumidity();
  float temperature1 = dht.getTemperature();
  
  // BM085
  dps.getPressure(&Pressure); 
  dps.getAltitude(&Altitude); 
  dps.getTemperature(&Temperature);
  
  byte second, minute, hour;
  getDateDs1307(&second, &minute, &hour);
  
// Вывод в порт  
//  Serial.print(hour, DEC);
//  Serial.print(":");
//  Serial.print(minute, DEC);
//  Serial.print(":");
//  Serial.println(second, DEC);
//  Serial.println(Pressure/133.3,1); // барометр BM085
//  Serial.println(Temperature*0.1,1); // термометр BM085
//  Serial.println(humidity,1);
//  Serial.println(temperature1,1);
  //выводим время                         
  lc.clearDisplay(0);
  for (int i=0; i <= 5; i++){
    lc.setDigit(0,0,(hour/10),false); //№ устройства,секция №,выводим значение,точка не горит - false
    lc.setDigit(0,1,(hour%10),false);
    lc.setDigit(0,3,(minute/10),false);
    lc.setDigit(0,4,(minute%10),false);
    lc.setDigit(0,2,14,false);
    delay(500);
    lc.setDigit(0,2,15,false);
    delay(500);
}
  
  lc.clearDisplay(0);
 //выводим температуру и влажность 
  T = round(Temperature*0.1-1);  // BMP085
//  T = round(temperature1);   // DHT11
  lc.setDigit(0,0,(T/10),false);
  lc.setDigit(0,1,(T%10),false);
  lc.setDigit(0,2,13,false);
  lc.setDigit(0,3,(humidity/10),false);
  lc.setDigit(0,4,(humidity%10),false);
  delay(3000);
  lc.clearDisplay(0);
 //выводим давление
  D=round(Pressure/133.3);
  lc.clearDisplay(0);
  lc.setDigit(0,1,(D/100),false);
  int b=D%100;
  lc.setDigit(0,2,(b/10),false);
  int c=b%10;
  lc.setDigit(0,3,c,false);
  delay(3000);
}

Решел вывести на улицу бепроводной датчик температуры используя rf24 433, сделал датчик автономный. Проверил отдельно, все работает, взял с примеров. Вот код приемника:

#include <VirtualWire.h>

void setup()
{
  Serial.begin(9600);
  vw_set_ptt_inverted(true); // Необходимо для DR3100
  vw_setup(2000); // Задаем скорость приема
  vw_rx_start(); // Начинаем мониторинг эфира
}

void loop()
{
  uint8_t buf[VW_MAX_MESSAGE_LEN]; // Буфер для сообщения
  uint8_t buflen = VW_MAX_MESSAGE_LEN; // Длина буфера

  if (vw_get_message(buf, &buflen)) // Если принято сообщение
  {
    // Начинаем разбор
    int i;
    // Если сообщение адресовано не нам, выходим
    if (buf[0] != 't')
    {
      return; 
    }
//    char command = buf[2]; // Команда находится на индексе 2
    
    // Числовой параметр начинается с индекса 4
    i = 3; 
    int tmp = 0;
    // Посколько передача идет посимвольно, то нужно преобразовать набор символов в число
    while (buf[i] != ' ')
    {
      tmp *= 10;
      tmp += buf[i] - '0';
      i++;
    }
//    Serial.print(command);
      Serial.println(tmp);
  }
}

Как только соединяю код, а именно вот это.

  vw_set_ptt_inverted(true); // Необходимо для DR3100
  vw_setup(2000); // Задаем скорость приема
  vw_rx_start(); // Начинаем мониторинг эфира

Программа вывода информации на дисплей перестает работать, похоже что контролер только слушает эфир и больше ничено. ПОДСКАЖИТЕ МОЖНО ЛИ ИХ СОВМЕСТИТЬ.

vvadim
Offline
Зарегистрирован: 23.05.2012

Надо поковырятся с совместимостью библиотек.

imv14
Offline
Зарегистрирован: 02.04.2014

Не подумал сразу VirtualWire и Wire, может они не стыкуются?

RomAndry
RomAndry аватар
Offline
Зарегистрирован: 20.02.2014

imv14 пишет:

Не подумал сразу VirtualWire и Wire, может они не стыкуются?

стыкуются

imv14
Offline
Зарегистрирован: 02.04.2014

Тогда в чем еще может быть проблема?

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

LedControl lc=LedControl(12,11,10,1);

VirtualWire если мне не изменяет память как раз 11 и 12 использует по умолчанию. Надо переопределить их vw_set_tx_pin(uint8_t pin)vw_set_rx_pin(uint8_t pin);

imv14
Offline
Зарегистрирован: 02.04.2014

У меня вот так называется 

// The digital IO pin number of the receiver data static uint8_t vw_rx_pin = 11;

// The digital IO pin number of the transmitter data static uint8_t vw_tx_pin = 12;
 
Менял, не помогает.
 
 
Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

Это из описания библиотеки

Библиотека VirtualWire использует в Ардуино Timer1, и это сказывается на работе PWM выводов 9 и 10.

imv14
Offline
Зарегистрирован: 02.04.2014

Всем спасибо за помощь. Перепаял все ноги как положено в библиотеке virtual, а в ledcontrole  в библитеке заменил, часы работают. Автономный датчик посылает данные раз в 24 секунды, время на вывод информации с датчиков уходит 10 секунд, так как прием и передача происходит в разное время, показания не приходят. Как правильно реализовать прием, что при этом еще и выполнялся цикл часов.

#include "Wire.h"
#include "LedControl.h"
#include "DHT.h"
#include <BMP085.h>
#define DS1307_I2C_ADDRESS 0x68
#include <VirtualWire.h>

DHT dht;

BMP085 dps = BMP085(); 
long Temperature = 0, Pressure = 0, Altitude = 0;

int T,D,H;

LedControl lc=LedControl(8,7,6,1); //(dataPin-1,clockPin-13,csPin-12,кол-во микросхем)
 
byte decToBcd(byte val)
{
  return ( (val/10*16) + (val%10) );
}
byte bcdToDec(byte val)
{
  return ( (val/16*10) + (val%16) );
}

void setDateDs1307(byte second,        // 0-59
                   byte minute,        // 0-59
	           byte hour)        // 0-99
{
  Wire.beginTransmission(DS1307_I2C_ADDRESS);
  Wire.write(0);
  Wire.write(decToBcd(second));   
  Wire.write(decToBcd(minute));
  Wire.write(decToBcd(hour));    
  Wire.endTransmission();
}
void getDateDs1307(byte *second,
	           byte *minute,
	           byte *hour)
{
  Wire.beginTransmission(DS1307_I2C_ADDRESS);
  Wire.write(0);
  Wire.endTransmission();
  Wire.requestFrom(DS1307_I2C_ADDRESS, 3);
	 *second     = bcdToDec(Wire.read());
	 *minute     = bcdToDec(Wire.read());
	 *hour       = bcdToDec(Wire.read()); 
}
void setup()
{
  dht.setup(2); // data pin 2
  
  byte second, minute, hour;
  Wire.begin();
  dps.init();      //BMP085   
  
  lc.shutdown(0,false);
  lc.setIntensity(0,8);
  lc.clearDisplay(0);
  
  pinMode(3, OUTPUT); 
  digitalWrite(3, HIGH);
  
  Serial.begin(9600);
// Установка времени
//    second = 00;
//    minute = 28;
//    hour = 12;
//    setDateDs1307(second, minute, hour);

  vw_set_ptt_inverted(true); // Необходимо для DR3100
  vw_setup(2000); // Задаем скорость приема
  vw_rx_start(); // Начинаем мониторинг эфира

}
void loop()
{
  delay(dht.getMinimumSamplingPeriod());
  int humidity = dht.getHumidity();
  float temperature1 = dht.getTemperature();
  
  // BM085
  dps.getPressure(&Pressure); 
  dps.getAltitude(&Altitude); 
  dps.getTemperature(&Temperature);
  
  byte second, minute, hour;
  getDateDs1307(&second, &minute, &hour);
  
// Вывод в порт  
//  Serial.print(hour, DEC);
//  Serial.print(":");
//  Serial.print(minute, DEC);
//  Serial.print(":");
//  Serial.println(second, DEC);
//  Serial.println(Pressure/133.3,1); // барометр BM085
//  Serial.println(Temperature*0.1,1); // термометр BM085
//  Serial.println(humidity,1);
//  Serial.println(temperature1,1);
  //выводим время                         
  lc.clearDisplay(0);
  for (int i=0; i <= 5; i++){
    lc.setDigit(0,0,(hour/10),false); //№ устройства,секция №,выводим значение,точка не горит - false
    lc.setDigit(0,1,(hour%10),false);
    lc.setDigit(0,3,(minute/10),false);
    lc.setDigit(0,4,(minute%10),false);
    lc.setDigit(0,2,14,false);
    delay(500);
    lc.setDigit(0,2,15,false);
    delay(500);
}
  
  lc.clearDisplay(0);
 //выводим температуру и влажность 
  T = round(Temperature*0.1-1);  // BMP085
//  T = round(temperature1);   // DHT11
  lc.setDigit(0,0,(T/10),false);
  lc.setDigit(0,1,(T%10),false);
  lc.setDigit(0,2,13,false);
  lc.setDigit(0,3,(humidity/10),false);
  lc.setDigit(0,4,(humidity%10),false);
  delay(3000);
  lc.clearDisplay(0);
 //выводим давление
  D=round(Pressure/133.3);
  lc.clearDisplay(0);
  lc.setDigit(0,1,(D/100),false);
  int b=D%100;
  lc.setDigit(0,2,(b/10),false);
  int c=b%10;
  lc.setDigit(0,3,c,false);
  delay(3000);
  
  uint8_t buf[VW_MAX_MESSAGE_LEN]; // Буфер для сообщения
  uint8_t buflen = VW_MAX_MESSAGE_LEN; // Длина буфера

  if (vw_get_message(buf, &buflen)) // Если принято сообщение
  {
    // Начинаем разбор
    int i;
    // Если сообщение адресовано не нам, выходим
    if (buf[0] != 't')
    {
      return; 
    }
    
    // Числовой параметр начинается с индекса 4
    i = 3; 
    int tmp = 0;
    // Посколько передача идет посимвольно, то нужно преобразовать набор символов в число
    while (buf[i] != ' ')
    {
      tmp *= 10;
      tmp += buf[i] - '0';
      i++;
    }
      Serial.println(tmp);
  }
}

 

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

Как я понял у Вас 5ть секунд показывается время потом 3и секунды температура и потом еще 3и секунды давление? Вам надо от delay избавиться. http://arduino.ru/tutorials/BlinkWithoutDelay вот тут написано как он него избавиться

UPD: причём желательно от всех delay

imv14
Offline
Зарегистрирован: 02.04.2014

Да, все правильно. Спасибо, сейчас постараюсь понять что там написано. Может, можно поставить прерывание на пин приема?

Transformer
Offline
Зарегистрирован: 20.09.2013

Всем привет. 
Помогите сделать правельную конструкцию кода. Я использую  две команды 19091 и 19090 для включения и выключения пина 9

if (code == 19091){digitalWrite(9, HIGH);}

if (code == 19090){digitalWrite(9, LOW);}

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

Таких пинов у меня 3

 

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

if(code=19091) digitalWrite(9, !digitalRead(9));

Transformer
Offline
Зарегистрирован: 20.09.2013

Огромное спасибо, поправил по вашему совету все работает. Подскажите пожалуйста как вставить delay задержку перед ожинанием следующей команды? бывает срабатывает сразу на вкл и выкл.

Код получается выглядет так

if(code == 19060){digitalWrite(9, !digitalRead(9));}
  else if(code == 19061){digitalWrite(8, !digitalRead(8));}
Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

delay не надо, достаточно code сбросить в 0 например, тогда код не выполнится пока code не станет снова 19091

if(code=19091)
{
  code = 0;
  digitalWrite(9, !digitalRead(9));
}

 

Transformer
Offline
Зарегистрирован: 20.09.2013

Супер. Спасибо еще раз вроде помагло стабилизировать.

imv14
Offline
Зарегистрирован: 02.04.2014

Вот убрал delay, все работает если не включать светодиодные цифры, как только зажигаю хотя бы одну, перестает принимать данные. Напряжение падает примерно на 0.1 вольт, может опускаться до 4.6-4.7вольт, может из-за этого.

#include "Wire.h"
#include "LedControl.h"
#include "DHT.h"
#include <BMP085.h>
#define DS1307_I2C_ADDRESS 0x68
#include <VirtualWire.h>
DHT dht;

BMP085 dps = BMP085(); 
long Temperature = 0, Pressure = 0, Altitude = 0;

int T,D,H,T3,humidity;
int tmp = 0;
float temperature1; 
long previousMillis = 0;        // храним время последнего переключения светодиода 
long interval = 4000;           // интервал между включение/выключением светодиода (1 секунда)
int var = 3;
  
LedControl lc=LedControl(8,7,6,1); //(dataPin-1,clockPin-13,csPin-12,кол-во микросхем)
 
byte decToBcd(byte val)
{
  return ( (val/10*16) + (val%10) );
}
byte bcdToDec(byte val)
{
  return ( (val/16*10) + (val%16) );
}

void setDateDs1307(byte second,        // 0-59
                   byte minute,        // 0-59
	           byte hour)        // 0-99
{
  Wire.beginTransmission(DS1307_I2C_ADDRESS);
  Wire.write(0);
  Wire.write(decToBcd(second));   
  Wire.write(decToBcd(minute));
  Wire.write(decToBcd(hour));    
  Wire.endTransmission();
}
void getDateDs1307(byte *second,
	           byte *minute,
	           byte *hour)
{
  Wire.beginTransmission(DS1307_I2C_ADDRESS);
  Wire.write(0);
  Wire.endTransmission();
  Wire.requestFrom(DS1307_I2C_ADDRESS, 3);
	 *second     = bcdToDec(Wire.read());
	 *minute     = bcdToDec(Wire.read());
	 *hour       = bcdToDec(Wire.read()); 
}

void setup()
{
  Serial.begin(9600);
  vw_set_ptt_inverted(true); // Необходимо для DR3100
  vw_setup(2000); // Задаем скорость приема
  vw_rx_start(); // Начинаем мониторинг эфира
  dht.setup(2); // data pin 2
  
  byte second, minute, hour;
  Wire.begin();
  dps.init();      //BMP085   
  
  lc.shutdown(0,false);
  lc.setIntensity(0,8);
  lc.clearDisplay(0);
  
  pinMode(3, OUTPUT); 
  digitalWrite(3, HIGH);
  
// Установка времени
//    second = 00;
//    minute = 28;
//    hour = 12;
//    setDateDs1307(second, minute, hour);
}

void loop()
{
  uint8_t buf[VW_MAX_MESSAGE_LEN]; // Буфер для сообщения
  uint8_t buflen = VW_MAX_MESSAGE_LEN; // Длина буфера

  if (vw_get_message(buf, &buflen)) // Если принято сообщение
  {
    // Начинаем разбор
    int i;
    // Если сообщение адресовано не нам, выходим
    if (buf[0] != 't')
    {
      return; 
    }
//    char command = buf[2]; // Команда находится на индексе 2
    
    // Числовой параметр начинается с индекса 4
    i = 3; 
    int tmp = 0;
    // Посколько передача идет посимвольно, то нужно преобразовать набор символов в число
    while (buf[i] != ' ')
    {
      tmp *= 10;
      tmp += buf[i] - '0';
      i++;
    }
      Serial.println(tmp);
  }
  byte second, minute, hour;
  getDateDs1307(&second, &minute, &hour);
  
  switch (var) {
    case 1://выводим время                                 
      lc.setDigit(0,0,(hour/10),false); //№ устройства,секция №,выводим значение,точка не горит - false
      lc.setDigit(0,1,(hour%10),false);
      lc.setDigit(0,3,(minute/10),false);
      lc.setDigit(0,4,(minute%10),false);
      lc.setDigit(0,2,14,false);
      lc.setDigit(0,2,15,false);   //закрашиваем тире
      break;
    case 2:   //выводим температуру и влажность   
      T = round(Temperature*0.1-1);  // BMP085
      lc.setDigit(0,0,(T/10),false);
      lc.setDigit(0,1,(T%10),false)   ;
      lc.setDigit(0,2,13,false);
      lc.setDigit(0,3,(humidity/10),false);
      lc.setDigit(0,4,(humidity%10),false);
      break; 
    case 3: 
      T3 = tmp*0.2727;
      lc.setDigit(0,0,12,false);
      if (T3 < 0){
        lc.setDigit(0,1,14,false);  
      }
      lc.setDigit(0,2,(T3/10),false);
      lc.setDigit(0,3,(T3%10),false);
      lc.setDigit(0,4,13,false);
      break;      
    case 4: //выводим давление
      D=round(Pressure/133.3);
      lc.setDigit(0,1,(D/100),false);
      int b=D%100;
      lc.setDigit(0,2,(b/10),false);
      int c=b%10;
      lc.setDigit(0,3,c,false);
      break;          
  }   
  unsigned long currentMillis = millis();
   if(currentMillis - previousMillis > interval) {//проверяем не прошел ли нужный интервал, если прошел то
     previousMillis = currentMillis; // сохраняем время последнего переключения
 // читаем влажность раз в 3 секунды
//     delay(dht.getMinimumSamplingPeriod());
     humidity = dht.getHumidity();
     float temperature1 = dht.getTemperature();
 // BM085
     dps.getPressure(&Pressure); 
     dps.getAltitude(&Altitude); 
     dps.getTemperature(&Temperature);
     lc.clearDisplay(0);     
     var = var+1;
     if (var == 5)
        var = 1;
   }
}

 

Penni
Penni аватар
Offline
Зарегистрирован: 18.01.2015

Может и из-за питания конечно. Меня смущает использование пина номер 1 для лсд. 1 это обычно TX, а Вы как раз сериал используете.

imv14
Offline
Зарегистрирован: 02.04.2014

LedControl lc=LedControl(8,7,6,1); для LCD использую 8,7,6. 1-это номер устройства микросхемы max. rx и tx незадействованны. Придется, наверно, на nrf2401 делать, вроде они меньше жрут.

RomAndry
RomAndry аватар
Offline
Зарегистрирован: 20.02.2014

я тоже хочу перейти на nrf2401 уж больно не стабильна связь на расстоянии 8-10 метров