Подскажите новичку - зацикливается программа

lues
Offline
Зарегистрирован: 10.06.2016

Всем привет.

Из кучи скетчей скомпилировал свое скетч.

Смысл простой - центральный модуль на Уно постоянно получает сигналы от термодатчиков по 433 мгц и через условное время данные через вай фай модуль ESP8266 отправляет на облако. Thingspeak в моем случае.

Все вопросы касаются именно работы с вай фаем.

1. Не могу понять причину зацикливания функции отправки пакета по вай фаю. Как только программа доходит до функции send () - она постоянно начинает слать пакеты по вай-фаю и уже не выходит обратно в основную программу из этой функции. 

Смысл в том что бы через millis задавать интервал отправки на сервер, что бы не дергать его сильно часто. А оно на отправке зацикливается...

Хотелось бы бы еще после этой функции другие проверки и вызовы нарисовать, а до них и не доходит...

и вторая проблема - совсем неясная: почему то в строке отправки данных умещается только 2 значения ,а хотелось бы 4.

запрос

con.send("GET /update?key=**************&field1="+a+"&field2="+b+" HTTP/1.1\r\n"); 

проходит нормально

а по сути аналогичный запрос

con.send("GET /update?key=****************&field1="+a+"&field2="+b+"&field3="+c+"&field4="+d+" HTTP/1.1\r\n"); 

не проходит..


  #include <SoftwareSerial.h>
  #include <ESP8266pro.h>
  #include <ESP8266proClient.h>
  #include <RCSwitch.h>

  RCSwitch mySwitch = RCSwitch();
  SoftwareSerial espSerial(9, 10); // задаем RX, TX esp8266
  ESP8266pro wifi(espSerial, Serial); // Serial, DebugSerial
  
  long starttime;
  long starttime1=0;
  long razn;
  float toffice1 = 25;
  float toffice2 = 26;
  float thome = 27;
  float tkotel = 28;
  String a;
  String b;
  String c;
  String d;
  const char* ssid = "*****";
  const char* password = "********";
  

  void setup() {
 
  espSerial.begin(9600);
  Serial.begin(9600);
  mySwitch.enableReceive(0);  // приемник на пин 2
  }
  
  void loop() {
  unsigned long starttime = millis ();//начинаем отсчет времени  
  unsigned long starttime1;
  if (mySwitch.available()) {
  float value = mySwitch.getReceivedValue();
  if (value > 11500 && value < 12000) toffice1 =((value - 11500)/10); 
  else if (value > 12500 && value < 13000) toffice2 =((value - 12500)/10);
  else if (value > 13500 && value < 14000) thome =((value - 13500)/10);
  else if (value > 14000 && value < 15000) tkotel =((value - 14500)/10);

  Serial.println(toffice1);  
  Serial.println(toffice2);  
  Serial.println(thome);   
  Serial.println(tkotel); 
  
  mySwitch.resetAvailable();
  }
  razn = (starttime - starttime1);
  starttime1 = starttime;
  if (razn > 120000) {
  Serial.println("Sending data thrugh wi-fi");
  send();
  }
  
  }


  //блок передачи***********************************************************
  void send() {

 // инициализация модуля -----------------------------------------------------------
  wifi.begin(eODM_Dump); // Disable all debug messages

  // подключение-------------------------------------------------------------------------
  do {
    if (!wifi.stationConnect(ssid, password))
      delay(5000);
     } 
  while (wifi.stationIP() == NULL_IP);
  Serial.print("ESP IP: ");
  Serial.println(wifi.stationIP());


   //передача-----------------------------------------------------------------------------
  String a(toffice1); 
  String b(toffice2);
  String c(thome); 
  String d(tkotel);  
  ESP8266proClient con(wifi, printResponse);
  con.connectTcp("184.106.153.149", 80);
  delay(500);
  con.send("GET /update?key=*************&field1="+a+"&field2="+b+" HTTP/1.1\r\n"); 
  delay(500);
  con.send("Host: api.thingspeak.com\r\n"); 
  delay(500);
  con.send("Accept: */*\r\n"); 
  delay(500);
  con.send("User-Agent: Mozilla/4.0 (compatible; esp8266 Lua; Windows NT 5.1)\r\n");
  delay(500);
  con.send("\r\n");
  delay(500);
  con.waitResponse();
  con.close();
  
  }
  
  // Optional method to process remote response------------------------------------------------
  void printResponse(ESP8266proConnection* connection, char* buffer, int length, boolean completed)
  {
  Serial.print(buffer);
  
  }

Помогите, голова кипит...

lues
Offline
Зарегистрирован: 10.06.2016

Хотя вот еще посидел и понял что с send() зацикливания нет...

Так как при мнимом зацикливании в сериалпорт каждый раз перед отправкой пакета идет фраза "Sending data thrugh wi-fi".

Получаеся что программа таки выходит из функции send () и начинает цикл заново, но почему тогда не работает задержка...??

Я явно что то или не понимаю в порядке работы программы или в структуре....

 

Помогите, плиз... У меня явно не работает вычисление задержки.

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

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

В строке 49 starttime1 используется ДО определения. Т.е. она объявлена в строке 34, но никакого значения не получает.

Кстати, компилятор должен был сказать об этом, включите вывод предупреждений - сэкономит кучу времени.

Araris
Offline
Зарегистрирован: 09.11.2012

Правильнее в строке 34 объявлять не как unsigned long starttime1; , а static unsigned long starttime1;

И удалить строки 10 и 11 за ненужностью.

lues
Offline
Зарегистрирован: 10.06.2016

Всеравно не понимаю...

При первом проходе программы у переменной starttime1 значенние 0, присвоенно в 11 строке и в строке 49 расчет происходит верно и тут задержка работает.

Далее в строке 50, переменная starttime1 получает текущее значени счетчика с переменной starttime.

В следующем цикле по идее уже должна вычисляться новая разница между starttime1 со статичным значением, присвоенным в прежнем цикле и starttime, которое увеличился за новый цикл...

Контроль ошибок я и не отключал.

Я туплю...   

__Alexander
Offline
Зарегистрирован: 24.10.2012

для компилятора это две разные переменные.

lues
Offline
Зарегистрирован: 10.06.2016

В первом коде была очевидная ошибка, присваивать переменной starttime1 значение starttime нужно при успешном прохождении условия сравнения,  а не вне функции If.

Это я исправил, но все равно задержка счетчика кроме первого раза не срабатывает.... 

 

#include <SoftwareSerial.h>

  #include <ESP8266pro.h>
  #include <ESP8266proClient.h>
  #include <RCSwitch.h>

  RCSwitch mySwitch = RCSwitch();
  SoftwareSerial espSerial(9, 10); // задаем RX, TX esp8266
  ESP8266pro wifi(espSerial, Serial); // Serial, DebugSerial
  


  float toffice1 = 25;
  float toffice2 = 26;
  float thome = 27;
  float tkotel = 28;
  String a;
  String b;
  String c;
  String d;
  const char* ssid = "*****";
  const char* password = "********";
  

  void setup() {
 
  espSerial.begin(9600);
  Serial.begin(9600);
  mySwitch.enableReceive(0);  // приемник на пин 2
  }
  
  void loop() {
  unsigned long starttime = millis ();//начинаем отсчет времени  
  unsigned long starttime1;
  
  if (mySwitch.available()) {
  float value = mySwitch.getReceivedValue();
  if (value > 11500 && value < 12000) toffice1 =((value - 11500)/10); 
  else if (value > 12500 && value < 13000) toffice2 =((value - 12500)/10);
  else if (value > 13500 && value < 14000) thome =((value - 13500)/10);
  else if (value > 14000 && value < 15000) tkotel =((value - 14500)/10);

  Serial.println(toffice1);  
  Serial.println(toffice2);  
  Serial.println(thome);   
  Serial.println(tkotel); 
  
  mySwitch.resetAvailable();
  }
  
  
  if (starttime >= (starttime1 + 30000)) {
  starttime1 = starttime;  
  Serial.println("Sending data through wi-fi");
  send();
  }
  }


  //блок передачи***********************************************************
  void send() {

 // инициализация модуля -----------------------------------------------------------
  wifi.begin(eODM_Dump); // Disable all debug messages

  // подключение-------------------------------------------------------------------------
  do {
    if (!wifi.stationConnect(ssid, password))
      delay(5000);
     } 
  while (wifi.stationIP() == NULL_IP);
  Serial.print("ESP IP: ");
  Serial.println(wifi.stationIP());


   //передача-----------------------------------------------------------------------------
  String a(toffice1); 
  String b(toffice2);
  String c(thome); 
  String d(tkotel);  
ESP8266proClient con(wifi, printResponse);
con.connectTcp("184.106.153.149", 80);
delay(1000);
con.send("GET /update?key=****************&field1="+a+"&field2="+b+" HTTP/1.1\r\n"); 
delay(1000);
con.send("Host: api.thingspeak.com\r\n"); 
delay(500);
con.send("Accept: */*\r\n"); 
delay(500);
con.send("User-Agent: Mozilla/4.0 (compatible; esp8266 Lua; Windows NT 5.1)\r\n");
con.send("\r\n");
con.waitResponse();
con.close();
  }
  

    
  
  // Optional method to process remote response------------------------------------------------
  void printResponse(ESP8266proConnection* connection, char* buffer, int length, boolean completed)
  {
  Serial.print(buffer);
  
  }

 

Araris
Offline
Зарегистрирован: 09.11.2012

lues пишет:

Всеравно не понимаю...

"статические переменные остаются после вызова функции, сохраняя свои значения между её вызовами."

http://arduino.ru/Reference/Static

__Alexander
Offline
Зарегистрирован: 24.10.2012

наоборот, сделай их глобальными, а в лупе не объявляй, а просто с ними работай.

lues
Offline
Зарегистрирован: 10.06.2016

Всем спасибо, уже разобрался.

 

TovBender
Offline
Зарегистрирован: 12.04.2015

.

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

В строке 38, если нет карты - вы выходите из loop, со всеми вытекающими, т.е. забиваете болт на то, что может быть сигнал с брелка. Навскидку переделанный код:

#include <SPI.h>

#include <MFRC522.h> 
#include <LiquidCrystal_I2C.h>
#include <RCSwitch.h>

LiquidCrystal_I2C lcd(0x27,16,2);  //  SDA - A4;  SCL - A5
RCSwitch mySwitch = RCSwitch();

#define SS_PIN 10
#define RST_PIN 9
#define ted 5  // замок с мотором   #5
#define tet 6  // замок с мотором
int but =0;

word Rkod=0;

MFRC522 mfrc522(SS_PIN, RST_PIN);  
unsigned long uidDec, uidDecTemp;
  
void setup() 
{

	Serial.begin(9600);     // Initialize serial communications with the PC.
	Serial.println("Prilozhite kartu .");
	//    lcd.init();  // Активировать дисплей
	//   lcd.backlight(); // подсветка дисплея
	//   lcd.print(" Zamok Nevidimka");
	SPI.begin();  //  инициализация SPI / Init SPI bus.
	mfrc522.PCD_Init();     // инициализация MFRC522 / Init MFRC522 card.

	pinMode(ted , OUTPUT);
	pinMode(tet , OUTPUT);
	mySwitch.enableReceive(0);  
   
}

void loop()  
{

   if (mfrc522.PICC_ReadCardSerial())
   {

		uidDec = 0;

		for (byte i = 0; i < mfrc522.uid.size; i++) 
		{
			uidDecTemp = mfrc522.uid.uidByte[i];
			uidDec = uidDec*256+uidDecTemp;  
		}  
  

		if (uidDec == 20460007958)        
		{
			digitalWrite(ted, HIGH);
			Serial.println(" Hi Liza"); 
		}
	}
  

	if (mySwitch.available())      
	{            
		Rkod= mySwitch.getReceivedValue();
		Serial.print(Rkod);     
		Serial.println();
                               
		if ( Rkod == 528 ) 
		{              
			digitalWrite(ted, HIGH); 
			delay(100); 
			digitalWrite(ted, LOW); 
			// lcd.setCursor(0, 1); 
			//  lcd.print("OTKRITO po Radio");
			Serial.println("Rabotaet ");
		}  
		
		mySwitch.resetAvailable(); // сброс радио кода
	}  
}

 

TovBender
Offline
Зарегистрирован: 12.04.2015

DIYMan

Подскажите как выйти из этой мёртвой петли.

DIYMan
DIYMan аватар
Offline
Зарегистрирован: 23.11.2015

TovBender пишет:

DIYMan

Подскажите как выйти из этой мёртвой петли.

В смысле выйти? return, но это ненадолго - в эту петлю опять зайдётся через ооочень короткий промежуток времени :)

TovBender
Offline
Зарегистрирован: 12.04.2015

подскажите где ошибка в коде

как использовать и радо кнопку, и RFID карты доступа ? радио брелок чтоб не идти до ворот, и не открывать в ручную, для тех у кого нет карт RFID/

по отдельности всё работает, если часть кода заремить.

 а вот вместе не работает.  Только карты доступа работают.