Arduino web server + Virtual wire

Подключение исполнительных устройств, датчиков, контроллеров.

Модератор: immortal

Аватара пользователя
sergejey
Site Admin
Сообщения: 4286
Зарегистрирован: Пн сен 05, 2011 6:48 pm
Откуда: Минск, Беларусь
Благодарил (а): 76 раз
Поблагодарили: 1559 раз
Контактная информация:

Arduino web server + Virtual wire

Сообщение sergejey » Ср авг 07, 2013 12:49 pm

Привет,

может кто сталкивался с такой проблемой -- есть Arduino с ethernet-shield-ом и модулем передатчика на 433Mhz. Хочу сделать так, чтобы при отправке определённого HTTP-запроса на контроллер, он посылал соответствующий пакет в эфир. Столкнулся с такой проблемой -- если в скетче используется одновременно web-сервер и virtualwire, то первый просто не отвечает, хотя контроллер работает и к нему можно подсоединиться по ком-порту, принять/отправить в него данные и т.п.

Ниже привожу полный скетч, но самая проблемная строчка это вот эта:

Код: Выделить всё

vw_setup(2000);
т.е. как только "завожу" VirtualWire, так веб-сервер не работает. убираю эту строчку и веб-сервер работает как положено, но, соответственно, не работает VirtualWire.

пробовал использовать другие PIN-ы для VirtualWire -- не помогает.

думаю может какой конфликт использования прерываний контроллера... если делать обратную связку, в которой контроллер выступает в роли веб-клиента, а VirtualWire используется как приёмник, то всё хорошо -- данные принимаются из эфира и передаются в ethernet-сеть. затык именно с веб-сервером.

может у знатоков какие идеи?

полный код скетча:

Код: Выделить всё

#include <Ethernet.h>
#include <SPI.h>
#include <VirtualWire.h>
#include <EasyTransferVirtualWire.h>

byte mac[] = { 0xDA, 0x7D, 0x5E, 0xDF, 0xCE, 0xED };
IPAddress ip(192,168,0,75);

String url = String(25);
int maxLength=25;

EthernetServer server(80);

#define PIN_LED 13
#define PIN_RF A0

//create object
EasyTransferVirtualWire ET; 

struct SEND_DATA_STRUCTURE{
  //put your variable definitions here for the data you want to send
  //THIS MUST BE EXACTLY THE SAME ON THE OTHER ARDUINO
  //Struct can'e be bigger then 26 bytes for VirtualWire version
  unsigned int device_id;
  unsigned int destination_id;    
  unsigned int packet_id;
  byte command;
  int data;
};

//give a name to the group of data
SEND_DATA_STRUCTURE mydata;

 
void setup() {

  pinMode(PIN_LED, OUTPUT);   // sets the pin as output
  
  Serial.begin(9600);
  // start the Ethernet connection and the server:
  Ethernet.begin(mac, ip);
  server.begin();
  
  Serial.print("server is at ");
  Serial.println(Ethernet.localIP()); 

  
  ET.begin(details(mydata));
  vw_set_tx_pin(PIN_RF);
  vw_setup(2000);        // !!!!!!!!
  
 
}

void loop() {
  char rcvChar;
  int  bCommandReady = false;

  // web server
  // listen for incoming clients
  EthernetClient client = server.available();
  //webClient = 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 (url.length() < maxLength) {
                    url+=(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) {
          
          
          Serial.println("Web request:");
          Serial.println(url);

          // send a standard http response header
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println("Connection: close"); 
          client.println();
          client.println("<!DOCTYPE HTML>");
          client.println("<html><head><title>Arduino</title></head><body>OK");
          bCommandReady = false;
          client.println("</body><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(1);
    // close the connection:
    url = "";
    client.stop();
     Serial.println("client disonnected");
  }  
  
}

Сергей Джейгало, разработчик MajorDoMo
Идеи, ошибки -- за предложениями по исправлению и развитию слежу только здесь!
Профиль Connect -- информация, сотрудничество, услуги
MaksMS82
Сообщения: 422
Зарегистрирован: Ср сен 05, 2012 7:30 am
Откуда: Киров
Благодарил (а): 0
Поблагодарили: 70 раз
Контактная информация:

Re: Arduino web server + Virtual wire

Сообщение MaksMS82 » Ср авг 07, 2013 1:08 pm

Пробовал принимать и расшифровывать команды от радиопульта - езернет работал криво и в итоге отваливался.Похоже две библиотеки,использующие активно прерывания не уживаются вместе..
Аватара пользователя
sergejey
Site Admin
Сообщения: 4286
Зарегистрирован: Пн сен 05, 2011 6:48 pm
Откуда: Минск, Беларусь
Благодарил (а): 76 раз
Поблагодарили: 1559 раз
Контактная информация:

Re: Arduino web server + Virtual wire

Сообщение sergejey » Ср авг 07, 2013 1:59 pm

MaksMS82 писал(а):Пробовал принимать и расшифровывать команды от радиопульта - езернет работал криво и в итоге отваливался.Похоже две библиотеки,использующие активно прерывания не уживаются вместе..
Приём (на другом контроллере) у меня как раз работает нормально и транслирует дальше по ethernet, а вот веб-сервер не заводится... Если ничего не придумаю, то придётся отказаться от Ethernet и подключать контроллер к USB. Хотя, не хотелось бы...

вот, кстати, если кому интересно код приёмника, который принимает данные от датчиков и передаёт их на MajorDoMo:

Код: Выделить всё

#include <VirtualWire.h>
#include <EasyTransferVirtualWire.h>
#include <EEPROM.h> //Needed to access the eeprom read write functions
#include <Ethernet.h>
#include <SPI.h>

const int led_pin = 13;
const int receive_pin = 2;
unsigned int unique_device_id = 0;

//create object
EasyTransferVirtualWire ET; 
char buf[120];

byte mac[] = { 0x00, 0x2A, 0xB6, 0x14, 0x38, 0xAC };
IPAddress server(192,168,0,17);
//IPAddress ip(192, 168, 0, 72);
EthernetClient client;

int ethernetAvailable=0;
unsigned long lastConnectionTime = 0;          // last time you connected to the server, in milliseconds
boolean lastConnected = false;                 // state of the connection last time through the main loop
unsigned int last_packet_id = 0;

struct SEND_DATA_STRUCTURE{
  //put your variable definitions here for the data you want to send
  //THIS MUST BE EXACTLY THE SAME ON THE OTHER ARDUINO
  //Struct can'e be bigger then 26 bytes for VirtualWire version
  unsigned int device_id;
  unsigned int destination_id;  
  unsigned int packet_id;
  byte command;
  int data;
};

//give a name to the group of data
SEND_DATA_STRUCTURE mydata;

//This function will write a 2 byte integer to the eeprom at the specified address and address + 1
void EEPROMWriteInt(int p_address, unsigned int p_value)
      {
      byte lowByte = ((p_value >> 0) & 0xFF);
      byte highByte = ((p_value >> 8) & 0xFF);

      EEPROM.write(p_address, lowByte);
      EEPROM.write(p_address + 1, highByte);
      }

//This function will read a 2 byte integer from the eeprom at the specified address and address + 1
unsigned int EEPROMReadInt(int p_address)
      {
      byte lowByte = EEPROM.read(p_address);
      byte highByte = EEPROM.read(p_address + 1);

      return ((lowByte << 0) & 0xFF) + ((highByte << 8) & 0xFF00);
      }

void sendHTTPRequest() {
  Serial.println(buf);   
  if (ethernetAvailable==1) {
   if (client.connected()) {
     client.stop();
   }
   if (client.connect(server, 80)) {
     Serial.println("connected");
     // Make a HTTP request:
     client.println(buf);
     client.println("User-Agent: arduino-ethernet");     
     client.println("Connection: close");     
     client.println();
     lastConnectionTime = millis();     
   } 
   else {
    Serial.println("connection failed");
    Serial.println("disconnecting.");    
    client.stop();
   } 
  }
}


void setup()
{
    pinMode(led_pin, OUTPUT);
    Serial.begin(9600); // Debugging only

  // start the Ethernet connection:
  if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet");
    ethernetAvailable=0;
  } else {
   ethernetAvailable=1;
   delay(1000);
   Serial.print("My IP address: ");
   Serial.println(Ethernet.localIP());   
  }

    ET.begin(details(mydata));
    // Initialise the IO and ISR
    vw_set_rx_pin(receive_pin);
    vw_setup(2000);      // Bits per sec
    vw_rx_start();       // Start the receiver PLL running
    
  // Device ID
  Serial.print("Getting Device ID... "); 
  unique_device_id=EEPROMReadInt(0);
  if (unique_device_id<10000 || unique_device_id>60000) {
   Serial.print("N/A, updating... "); 
   unique_device_id=random(10000, 60000);
   EEPROMWriteInt(0, unique_device_id);
  }
  Serial.println(unique_device_id);
  
}

void loop()
{
  
    if (client.available()) {
    char c = client.read();
    Serial.print(c);
  }  
  if (!client.connected() && lastConnected) {
    Serial.println();
    Serial.println("disconnecting.");
    client.stop();
  } 
  
    if(ET.receiveData())
    {
        digitalWrite(led_pin, HIGH);
        Serial.print("Got: ");
        Serial.print("Device ID: ");
        Serial.print(mydata.device_id);
        Serial.print(" Destination ID: ");
        Serial.print(mydata.destination_id);        
        Serial.print(" Packet ID: ");
        Serial.print(mydata.packet_id);
        Serial.print(" Command: ");
        Serial.print(mydata.command);
        Serial.print(" Data: ");
        Serial.print(mydata.data);
        Serial.println();
                if (last_packet_id!=(int)mydata.packet_id) {
         sprintf(buf, "GET /objects/?script=easyRF&did=%u&dest=%u&pid=%u&c=%u&d=%i HTTP/1.0", (int)mydata.device_id, (int)mydata.destination_id, (int)mydata.packet_id, (int)mydata.command, (int)mydata.data);
                 last_packet_id=(int)mydata.packet_id;
         sendHTTPRequest();
                }
        Serial.println();        
        digitalWrite(led_pin, LOW);             
    }
    
   lastConnected = client.connected(); 
    
}

Сергей Джейгало, разработчик MajorDoMo
Идеи, ошибки -- за предложениями по исправлению и развитию слежу только здесь!
Профиль Connect -- информация, сотрудничество, услуги
Menen
Сообщения: 4
Зарегистрирован: Вс июл 28, 2013 7:16 pm
Благодарил (а): 0
Поблагодарили: 0

Re: Arduino web server + Virtual wire

Сообщение Menen » Чт авг 08, 2013 8:57 am

SPI использует 13 вывод
MaksMS82
Сообщения: 422
Зарегистрирован: Ср сен 05, 2012 7:30 am
Откуда: Киров
Благодарил (а): 0
Поблагодарили: 70 раз
Контактная информация:

Re: Arduino web server + Virtual wire

Сообщение MaksMS82 » Чт авг 08, 2013 9:40 am

Menen писал(а):SPI использует 13 вывод
Это на UNO ,а на МЕГА - нет

Кстати,заметил что на шилде W5100 нет перемычки на 2 ногу для прерывания -вроде как его можно задействовать,но упоминания про это нигде не видел..
Аватара пользователя
sergejey
Site Admin
Сообщения: 4286
Зарегистрирован: Пн сен 05, 2011 6:48 pm
Откуда: Минск, Беларусь
Благодарил (а): 76 раз
Поблагодарили: 1559 раз
Контактная информация:

Re: Arduino web server + Virtual wire

Сообщение sergejey » Ср авг 14, 2013 3:54 pm

Разобрался я с той проблемой. Пришлось залезть в исходники VirtualWire и посмотреть что к чему.
Короче, библиотека устанавливает типы выводов для RX(приёма) и PTT(push-to-talk), даже если мне нужно только отправлять данные и PTT у меня не используется. А заданные по-умолчанию они совпадают с используемыми для ethernet-шилда, вот они и конфликтовали.

В итоге вместо:

Код: Выделить всё

vw_set_tx_pin(PIN_RF);
vw_setup(2000);
Поставил для инициализации:

Код: Выделить всё

vw_set_tx_pin(PIN_RF);
vw_set_rx_pin(A1); // не используемый выход
vw_set_ptt_pin(A2);  // не используемый выход
vw_setup(2000);
Теперь всё нормально заработало и я могу через HTTP-запросы посылать команды исполнительным устройства по радио-каналу.

Итоговое устройство содержит блок реле (8 штук), модуль передатчика на 433Mhz, ethernet-shield и имеет IP-адрес 192.168.0.75 и понимает следующие запросы:

http://192.168.0.75/ или http://192.168.0.75/?HELP -- выдаёт список команд
http://192.168.0.75/?LED,уровень -- установка уровня яркости светодиода (планировалось, но не используется)
http://192.168.0.75/?ON,выход -- включение реле на указанном выходе (используются выходы со 2-ого по 9-ый)
http://192.168.0.75/?OFF,выход -- выключение реле на указанном выходе
http://192.168.0.75/?STATE,выход -- возвращает текущее состояние выхода
http://192.168.0.75/?CLICK,выход -- кратковременное включение и затем выключение реле на указанном выходе
http://192.168.0.75/?LCLICK,выход -- более длительное включение и затем выключение реле на указанном выходе
http://192.168.0.75/?RCLICK,значение -- в зависимости от значения (1,2,3) включается определённая комбинация реле (это уже мои заморочки, можно не использовать)
http://192.168.0.75/?RF,устройство-команда-значение -- отправка нужной команды со значением на указанное устройство (трёх-кратная передача пакета)

Думаю ещё немного доработать, чтоб модуль передатчика можно было использовать для отправки команд включения/выключения на китайские радио-управляемые розетки.

По схематике всё просто -- на выходы 2-9 подключен блок реле, на аналоговый A0 подключен блок передатчика. Ну и питание соответственно.

3-й или 4-й выход (точно не помню) так же оказывается используется ethernet-шилдом, так что одна релюшка у меня выпадает и её надо куда-то переподключить будет. в остально простая и довольно удобная штуковина получилась :)

Итоговый скетч:

Код: Выделить всё

// Universal Arduino controller for MajorDoMo (http://smartliving.ru)
// v 0.1

#include <Ethernet.h>
#include <SPI.h>
#include <VirtualWire.h>
#include <EasyTransferVirtualWire.h>
#include <EEPROM.h> //Needed to access the eeprom read write functions


#define MAX_COMMAND_LEN             (10)
#define MAX_PARAMETER_LEN           (30)
#define COMMAND_TABLE_SIZE          (10)
#define TO_UPPER(x) (((x >= 'a') && (x <= 'z')) ? ((x) - ('a' - 'A')) : (x))

// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = { 0xDA, 0x7D, 0x5E, 0xDF, 0xCE, 0xED };
//byte ip[] = { 192,168,0,75 };
IPAddress ip(192,168,0,75);
//byte pingAddr [] = {192, 168, 0, 1};
//SOCKET pingSocket = 0;

String url = "";
int maxLength=25;

// Initialize the Ethernet server library
// with the IP address and port you want to use
// (port 80 is default for HTTP):
EthernetServer server(80);
EthernetClient webClient;

#define PIN_LED A3
#define PIN_LED_T A3 
#define PIN_RF A0
#define RF_SEND_COUNTER 3

int webRequest = false; // is command requested by HTTP?
int startPin=2;
int endPin=9; // 10,11,12,13 used by ethernet shield,


//create object
EasyTransferVirtualWire ET; 

struct SEND_DATA_STRUCTURE{
  //put your variable definitions here for the data you want to send
  //THIS MUST BE EXACTLY THE SAME ON THE OTHER ARDUINO
  //Struct can'e be bigger then 26 bytes for VirtualWire version
  unsigned int device_id;
  unsigned int destination_id;    
  unsigned int packet_id;
  byte command;
  int data;
};
unsigned int unique_device_id = 0;

//give a name to the group of data
SEND_DATA_STRUCTURE mydata;


char gCommandBuffer[MAX_COMMAND_LEN + 1];
char gParamBuffer[MAX_PARAMETER_LEN + 1];
String commandReceived;
String parametersReceived;
            
long gParamValue;



typedef struct {
  char const    *name;
  void          (*function)(void);
} command_t;

command_t const gCommandTable[COMMAND_TABLE_SIZE] = {
  {"HELP",    commandsHelp,},
  {"LED",     commandsLed, },
  {"ON",     commandsOn, },  
  {"OFF",     commandsOff, },    
  {"STATE",     commandsState, },      
  {"CLICK",     commandsClick, },        
  {"LCLICK",     commandsLClick, }, 
  {"RCLICK",     commandsRClick, },
  {"RF",     commandsRF, },   
  {NULL,      NULL }
};


//This function will write a 2 byte integer to the eeprom at the specified address and address + 1
void EEPROMWriteInt(int p_address, unsigned int p_value)
{
  byte lowByte = ((p_value >> 0) & 0xFF);
  byte highByte = ((p_value >> 8) & 0xFF);

  EEPROM.write(p_address, lowByte);
  EEPROM.write(p_address + 1, highByte);
}

//This function will read a 2 byte integer from the eeprom at the specified address and address + 1
unsigned int EEPROMReadInt(int p_address)
{
  byte lowByte = EEPROM.read(p_address);
  byte highByte = EEPROM.read(p_address + 1);

  return ((lowByte << 0) & 0xFF) + ((highByte << 8) & 0xFF00);
}


void blinking(int count) {
 for(int i=0;i<count;i++) {
  digitalWrite(PIN_LED, HIGH); 
  delay(200);
  digitalWrite(PIN_LED, LOW);
  delay(200);
 }
}


void sendRFData() {
 Serial.print("Transmitting packets ... ");   
 for(int i=0;i<RF_SEND_COUNTER;i++) {
  if (i>0) {
   delay(200);    
  }
  digitalWrite(PIN_LED_T, HIGH); 
  ET.sendData();
  digitalWrite(PIN_LED_T, LOW);
 }  
 Serial.println("DONE");   
}



 void printLine(const char line[]) {
 if (webRequest) {
  if (webClient) {
   if (webClient.connected()) {
    webClient.println(line);
    webClient.println("<br/>");
   }
  }
} else {
   Serial.println(line);
}

 }
  

int cliBuildCommand(char nextChar) {
  static uint8_t idx = 0; //index for command buffer
  static uint8_t idx2 = 0; //index for parameter buffer
  enum { COMMAND, PARAM };
  static uint8_t state = COMMAND;
  
  if ((nextChar == '\n') || (nextChar == ' ') || (nextChar == '\t') || (nextChar == '\r'))
    return false;

  
  //if (nextChar == '\r') {
  if (nextChar == ';') {
    gCommandBuffer[idx] = '\0';
    gParamBuffer[idx2] = '\0';
    idx = 0;
    idx2 = 0;
    state = COMMAND;
    return true;
  }

  if (nextChar == ',') {
    state = PARAM;
    return false;
  }

  if (state == COMMAND) {
    
    gCommandBuffer[idx] = TO_UPPER(nextChar);
    idx++;

    
    if (idx > MAX_COMMAND_LEN) {
      idx = 0;
       return true;
    }
  }

  if (state == PARAM) {
    
    gParamBuffer[idx2] = nextChar;
    idx2++;

    
    if (idx > MAX_PARAMETER_LEN) {
      idx2 = 0;
      return true;
    }
  }

  return false;
}


void cliProcessCommand(void)
{
  int bCommandFound = false;
  int idx;

  
  gParamValue = strtol(gParamBuffer, NULL, 0);

  
  for (idx = 0; gCommandTable[idx].name != NULL; idx++) {
    if (strcmp(gCommandTable[idx].name, gCommandBuffer) == 0) {
      bCommandFound = true;
      break;
    }
  }

  
  if (bCommandFound == true) {
    if (!webRequest) {
     printLine("");
    }
    (*gCommandTable[idx].function)();
  }
  else {
    if (!webRequest) {
     printLine("");
    }
    printLine("Command not found:");
    printLine(gCommandBuffer);
  }
}


void commandsLed(void) {
  printLine("LED command received.");
 
  if (gParamValue >=0 && gParamValue <= 255) {
    analogWrite(PIN_LED, gParamValue);
  }
  else {
    printLine("wrong parameter value");
  }
}

void commandsOn(void) {
  printLine("ON command received.");
  if (gParamValue>=startPin && gParamValue<=endPin) {
     printLine("Turning ON");
     digitalWrite(gParamValue,LOW);
  } else {
    printLine("Incorrect PIN");
  }
}

void commandsOff(void) {
  printLine("OFF command received.");
  if (gParamValue>=startPin && gParamValue<=endPin) {
     printLine("Turning OFF");
     digitalWrite(gParamValue,HIGH);
  } else {
    printLine("Incorrect PIN");
  } 
}

void commandsClick(void) {
  printLine("CLICK command received.");
  if (gParamValue>=startPin && gParamValue<=endPin) {
     printLine("Clicking");
     digitalWrite(gParamValue,LOW);     
     delay(1000);
     digitalWrite(gParamValue,HIGH);
     
  } else {
    printLine("Incorrect PIN");
  } 
}

void commandsLClick(void) {
  printLine("LCLICK command received.");
  digitalWrite(6,LOW);
  if (gParamValue==1) {
     digitalWrite(9,LOW);
     delay(2000);
     digitalWrite(9,HIGH);
  }
  if (gParamValue==2) {
     digitalWrite(8,LOW);     
     delay(2000);
     digitalWrite(8,HIGH);    
  }  
  if (gParamValue==3) {
     digitalWrite(7,LOW);     
     delay(2000);
     digitalWrite(7,HIGH);    
  }    
  digitalWrite(6,HIGH);
}

void commandsRClick(void) {
  printLine("RCLICK command received.");
  
  digitalWrite(5,LOW);
  if (gParamValue==1) {
     digitalWrite(9,LOW);
     delay(2000);
     digitalWrite(9,HIGH);
  }
  if (gParamValue==2) {
     digitalWrite(8,LOW);     
     delay(2000);
     digitalWrite(8,HIGH);    
  }  
  if (gParamValue==3) {
     digitalWrite(7,LOW);     
     delay(2000);
     digitalWrite(7,HIGH);    
  }    
  digitalWrite(5,HIGH);
}

void commandsRF(void) {
  printLine("RF command received");
  printLine(gParamBuffer);
  //gParamBuffer
  //to-command-data
  //parametersReceived
  String paramString;
  unsigned int destination_id=0;
  byte command=0;
  int data=0;
  int splitPosition;
  splitPosition=parametersReceived.indexOf('-');
  if(splitPosition != -1) {
   paramString=parametersReceived.substring(0,splitPosition);
   destination_id=paramString.toInt();
   parametersReceived=parametersReceived.substring(splitPosition+1,parametersReceived.length());
   splitPosition=parametersReceived.indexOf('-');
   if(splitPosition != -1) {
    paramString=parametersReceived.substring(0,splitPosition);
    command=paramString.toInt();
    parametersReceived=parametersReceived.substring(splitPosition+1,parametersReceived.length());
    data=parametersReceived.toInt();    
   }
  }
  
     mydata.packet_id = random(65535);
     mydata.command = command;
     mydata.data = data;
     mydata.destination_id = destination_id;
     sendRFData();  
     
     
  //gparam
}

void commandsState(void) {
  for(int i=startPin;i<=endPin;i++) {
    int st=digitalRead(i);
    char my_st[5];
    itoa(st,my_st,10);
//    printLine("PIN"+i);
    printLine(my_st);
  }
}

void commandsHelp(void) {
  int idx;
  
  
  for (idx = 0; gCommandTable[idx].name != NULL; idx++) {
    printLine(gCommandTable[idx].name);   
  }
  
}


void setup() {

  pinMode(PIN_LED_T, OUTPUT);   
  pinMode(PIN_LED, OUTPUT);   // sets the pin as output
  for (int thisPin = startPin; thisPin <=endPin; thisPin++)  {
    pinMode(thisPin, OUTPUT);      
    digitalWrite(thisPin,HIGH);
  }
  
  delay(200);
  
  Serial.begin(9600);
  // start the Ethernet connection and the server:
  Ethernet.begin(mac, ip);
  server.begin();
  
  Serial.print("server is at ");
  Serial.println(Ethernet.localIP()); 

  Serial.println("Arduino command processing example");
  Serial.print('>');
  
  
  ET.begin(details(mydata));
  
  vw_set_tx_pin(PIN_RF);
  vw_set_rx_pin(A1);
  vw_set_ptt_pin(A2); 
  //vw_set_ptt_inverted(true);
  
  vw_setup(2000);        // Bits per sec
  
  randomSeed(analogRead(0));
  
  
  // Device ID
  Serial.print("Getting Device ID... "); 
  
  unique_device_id=EEPROMReadInt(0);
  //unique_device_id=0;
  if (unique_device_id<10000 || unique_device_id>60000) {
    Serial.print("N/A, updating... "); 
    unique_device_id=random(10000, 60000);
    EEPROMWriteInt(0, unique_device_id);
  }
  Serial.println(unique_device_id);   
  mydata.device_id = unique_device_id;
  mydata.destination_id = 0;   
  
  
}

void loop() {
  char rcvChar;
  int  bCommandReady = false;


  if (Serial.available() > 0) {
    rcvChar = Serial.read();
    Serial.print(rcvChar);
    bCommandReady = cliBuildCommand(rcvChar);
  }

 if (bCommandReady == true) {
    webRequest = false;
    bCommandReady = false;
    cliProcessCommand();
    Serial.print('>');
  }
  
 
  
  // web server
  // listen for incoming clients
  EthernetClient client = server.available();
  webClient = client;
  //webClient = 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 (url.length() < maxLength) {
                    url+=(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) {
          
          
          Serial.print("HTTP request: ");
          Serial.println(url);

          if (url.indexOf("?")>=0) {

            int PosB=url.indexOf("?")+1;
            int PosE=url.indexOf("HTTP");
            if (url.indexOf(",")>=0) {
              // command has parameters              
              int PosP=url.indexOf(",");
              commandReceived=url.substring(PosB,PosP);              
              parametersReceived=url.substring(PosP+1,PosE-1);              
            } else {
              // command does not have parameters
              commandReceived=url.substring(PosB,PosE-1);              
              parametersReceived="";
            }
            //Serial.print("Command: ");
            //Serial.println(commandReceived);
            //Serial.print("Parameter: ");
            //Serial.println(parametersReceived);
            
            commandReceived.toUpperCase();
            parametersReceived.toUpperCase();
            //strcpy (gCommandBuffer, commandReceived.toCharArray());
            commandReceived.toCharArray(gCommandBuffer,commandReceived.length()+1);
            
            if (parametersReceived.length()>0) {              
             //strcpy (gParamBuffer, parametersReceived.toCharArray());
             parametersReceived.toCharArray(gParamBuffer,parametersReceived.length()+1);
            }
           
          } else {
           //no command defined, showing help string
           strcpy (gCommandBuffer, "HELP\0");
          }
          
          
          // send a standard http response header
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println("Connection: close"); 
          client.println();
          client.println("<!DOCTYPE HTML>");
          client.println("<html><head><title>Arduino</title></head><body>");
          webRequest = true;
          bCommandReady = false;
          
          cliProcessCommand();
          client.println("</body><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(1);
    // close the connection:
    url = "";
    client.stop();
     Serial.println("client disonnected");
  }  
  
}


Сергей Джейгало, разработчик MajorDoMo
Идеи, ошибки -- за предложениями по исправлению и развитию слежу только здесь!
Профиль Connect -- информация, сотрудничество, услуги
MaksMS82
Сообщения: 422
Зарегистрирован: Ср сен 05, 2012 7:30 am
Откуда: Киров
Благодарил (а): 0
Поблагодарили: 70 раз
Контактная информация:

Re: Arduino web server + Virtual wire

Сообщение MaksMS82 » Ср авг 14, 2013 4:11 pm

Как раз пытаю радио модули 433мгц для передачи некоторых данных на часы-монитор.Но использую простую отправку целых цифр через библиотеку RemoteSwitch ,например:
передаем температуру - температура*10+500 =цифра
по приему - (цифра-500)/10=температура
Данные отправляет контроллер на ардуино+езернет.Но в данный момент тестирую USB-передатчик ( сделаный из USBasp программатора за 3$) для отправки данных на часы ( или управления розетками) - пока просто для теста и оттачивания си на AVR М/К
Аватара пользователя
sergejey
Site Admin
Сообщения: 4286
Зарегистрирован: Пн сен 05, 2011 6:48 pm
Откуда: Минск, Беларусь
Благодарил (а): 76 раз
Поблагодарили: 1559 раз
Контактная информация:

Re: Arduino web server + Virtual wire

Сообщение sergejey » Ср авг 14, 2013 5:27 pm

MaksMS82 писал(а):Как раз пытаю радио модули 433мгц для передачи некоторых данных на часы-монитор.Но использую простую отправку целых цифр через библиотеку RemoteSwitch ,например:
передаем температуру - температура*10+500 =цифра
по приему - (цифра-500)/10=температура
Данные отправляет контроллер на ардуино+езернет.Но в данный момент тестирую USB-передатчик ( сделаный из USBasp программатора за 3$) для отправки данных на часы ( или управления розетками) - пока просто для теста и оттачивания си на AVR М/К
Может быть пригодится: http://smartliving.ru/Main/ArduinoVirtualWire
Я здесь описываю протокол, который у себя для обмена использую.

Сергей Джейгало, разработчик MajorDoMo
Идеи, ошибки -- за предложениями по исправлению и развитию слежу только здесь!
Профиль Connect -- информация, сотрудничество, услуги
MaksMS82
Сообщения: 422
Зарегистрирован: Ср сен 05, 2012 7:30 am
Откуда: Киров
Благодарил (а): 0
Поблагодарили: 70 раз
Контактная информация:

Re: Arduino web server + Virtual wire

Сообщение MaksMS82 » Чт авг 15, 2013 7:29 am

sergejey писал(а):
MaksMS82 писал(а):Как раз пытаю радио модули 433мгц для передачи некоторых данных на часы-монитор.Но использую простую отправку целых цифр через библиотеку RemoteSwitch ,например:
передаем температуру - температура*10+500 =цифра
по приему - (цифра-500)/10=температура
Данные отправляет контроллер на ардуино+езернет.Но в данный момент тестирую USB-передатчик ( сделаный из USBasp программатора за 3$) для отправки данных на часы ( или управления розетками) - пока просто для теста и оттачивания си на AVR М/К
Может быть пригодится: http://smartliving.ru/Main/ArduinoVirtualWire
Я здесь описываю протокол, который у себя для обмена использую.
Да ,Читал,но возможно и удобен и вариант через RemoteSwitch,вот часы+монитор с приемником:

Код: Выделить всё

#include <RemoteReceiver.h>
#include <LiquidCrystal.h>
#include <Wire.h>
#include <DS1307.h> // written by  mattt on the Arduino forum and modified by D. Sjunnesson


int tempout=555,tempin=555,seth=555;



LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

void setup() {
  lcd.begin(16, 2);
 pinMode(13, OUTPUT); 
 RemoteReceiver::init(4, 3, showCode);
}

int sec,mins;

unsigned long dd;
void loop() {
  if(seth !=555){
     RTC.stop();
  RTC.set(DS1307_SEC,1);        //set the seconds
  RTC.set(DS1307_MIN,0);     //set the minutes
  RTC.set(DS1307_HR,seth);       //set the hours
//  RTC.set(DS1307_DOW,6);       //set the day of the week
//  RTC.set(DS1307_DATE,11);       //set the date
//  RTC.set(DS1307_MTH,8);        //set the month
//  RTC.set(DS1307_YR,13);         //set the year
 RTC.start();
  seth =555;
  }
  
  lcd.setCursor(0, 0);
  
    lcd.print(RTC.get(DS1307_HR,true)); //read the hour and also update all the values by pushing in true
  lcd.print(":");
  
  mins=RTC.get(DS1307_MIN,false);
  if (mins<10)lcd.print('0');
  lcd.print(mins);
  
  lcd.print(":");
  
  sec=RTC.get(DS1307_SEC,false);//read seconds
  
  if (sec<10)lcd.print('0');//read seconds
  lcd.print(sec);

   lcd.print(" ");

  lcd.setCursor(0, 1);
  lcd.print("St:");
if(tempout==555) lcd.print("---");
else lcd.print((float)tempout/10,1);
lcd.setCursor(8, 1);
  lcd.print(" R:");
  if(tempin==555) lcd.print("---");
else   lcd.print((float)tempin/10,1);
    lcd.print(" ");
}

#define key1  400000 // датчик температуры
#define key2  403000 // датчик температуры
#define key3  405000 // синхронизация часов

void showCode(unsigned long receivedCode, unsigned int period) {
digitalWrite(13, 1);
  
       if (key1<receivedCode && key1+1000>receivedCode) tempout=receivedCode-key1-500;
       
  else if (key2<receivedCode && key2+1000>receivedCode) tempin=receivedCode-key2-500;
  
  else if (key3<receivedCode && key3+1000>receivedCode) seth=receivedCode-key3;
  
 
 digitalWrite(13, 0);
 // тут ещё имеется переменная period,которую можно тоже проверять.В передатчике она установлена 300.
}
Передатчик пример,в реальном скетче это все идет через get запрос ethernet модуля в виде цифры,которая вычисляется на компе:

Код: Выделить всё

#include <RemoteSwitch.h>


float tempout=-25.46;
float tempin=30.64;

#define key1  400000
#define key2  403000
#define key3  405000

void setup() {
}

void loop() {  



senddata(tempout*10+key1+500);

senddata(tempin*10+key2+500);

//senddata(час+key3); подать который час для синхронизации часов..

delay(1000);

}

void senddata(unsigned long code) {
  
  code |= (unsigned long)[color=#FF0000]300[/color] << 23; // красным выделен период импульсов.
  code |= 3L << 20;
  RemoteSwitch::sendTelegram(code,2);  
  
}
Это пока просто наработка,но уже протестировано .Ключи KeyХ могут быть любыми,но не выходить за пределы 531 440 включая диапазон внутри пакета данных.
Большой плюс в таком способе - это намного меньший скетч и пакет в эфире занимает ещё меньше времени передачи..
По идее выделив период из подпрограммы senddata и проверяя его при приеме можно увеличить количество кодов значительно:

Код: Выделить всё

void senddata(unsigned long code,int period) {
  
  code |= (unsigned long)period << 23;
  code |= 3L << 20;
  RemoteSwitch::sendTelegram(code,2);  
}
pdmitry2
Сообщения: 90
Зарегистрирован: Ср фев 06, 2013 1:12 pm
Откуда: Россия, Москва
Благодарил (а): 35 раз
Поблагодарили: 6 раз

Re: Arduino web server + Virtual wire

Сообщение pdmitry2 » Сб сен 21, 2013 5:39 pm

Помогите пожалуйста разобраться. Имеется во такой простой скетч, взятый у Сергея вот в этой теме http://smartliving.ru/Main/ArduinoCode и немного переделанный

Код: Выделить всё

#include <Ethernet.h>
#include <SPI.h>

// MAC-адрес нашего устройства
byte mac[] = { 0x00, 0x2A, 0xF6, 0x12, 0x68, 0xFC };
// ip-адрес устройства
byte ip[] = { 192, 168, 1, 20 };
// ip-адрес удалённого сервера
byte server[] = { 192, 168, 1, 105 }; // измените на свой

int old_Door=0;
int old_movement=0;
char buf[80];

Client rclient(server, 80); // 80-порт.

// Функция отправки HTTP-запроса на сервер
void sendHTTPRequest() {
  Serial.println(buf); 
  if (rclient.connect()) { 
   Serial.println("OK"); 
   rclient.println(buf);
   rclient.println("Host: 192.168.1.105");
   rclient.println();   
   delay(2000);
   rclient.stop();
  } else {
   Serial.println("FAILED");     
  }

}


void setup()
{
 Ethernet.begin(mac, ip); // Инициализируем Ethernet Shield

 pinMode(7, INPUT); // Датчик входной двери на 7-ой пин
 old_Door=digitalRead(7);
 pinMode(8, INPUT); // Датчик движения
 old_movement=digitalRead(8);


 Serial.begin(115200); // Скорость консольного порта 115200 (пригодится для отладки)
}

void loop()
{

  int valid_sensor=0;

  delay(1000); // задержка в 1 сек.  

  //Door SENSOR
  Serial.println("Door");
  int current_Door=digitalRead(7);
  Serial.println(current_Door);
  if (current_Door!=(int)old_Door) {
    old_Door=(int)current_Door;
    sprintf(buf, "GET /objects/?object=sensorDoor&op=m&m=statusChanged&status=%i HTTP/1.0", (int)current_Door);
    sendHTTPRequest();
  }

 //MOVEMENT SENSOR
  Serial.println("Movement");
  int current_movement=digitalRead(8);
  Serial.println(current_movement);
  if (current_movement!=(int)old_movement) {
    old_movement=(int)current_movement;
    sprintf(buf, "GET /objects/?object=sensorMovement&op=m&m=statusChanged&status=%i HTTP/1.0", (int)current_movement);
    sendHTTPRequest();
  }
 }
Есть так же приёмник на 433 Mhz. и есть радиокнопка которая работает на этой же частоте. Мне нужно, что бы по нажатии на эту кнопку, в MDM отправлялся информация о том, что кнопка была нажата. То есть - нажимаем на кнопку, ардуина "видит", что нажата кнопка с кодом ХХХХХ и посылает в MDM запрос вида GET /objects/?object=sensorКНОПКА&op=m&m=statusChanged&status=%i HTTP/1.0, а MDM в свою очередь сообщает мне о нажатии этой кнопки. Примеров работы приёмников вроде много в сети, но самому разобраться не получается. Подскажите пожалуйста, если не сложно, пример кода, который нужно добавить в этот скетч?
Ответить