Browse Source

Version 6.2.0; OLED output improved. Repair sensor totals on webpage

platenspeler 5 năm trước cách đây
mục cha
commit
093f3d35bb

+ 8 - 1
CHANGELOG.md

@@ -1,6 +1,6 @@
 # Single Channel LoRaWAN Gateway
 
-Version 6.1.8, January 15, 2020 
+Version 6.2.0, January 24, 2020 
 Author: M. Westenberg (mw12554@hotmail.com)  
 Copyright: M. Westenberg (mw12554@hotmail.com)  
 
@@ -16,6 +16,13 @@ Maintained by Maarten Westenberg (mw12554@hotmail.com)
 
 # Release Notes
 
+Features release 6.2.0 (January 29, 2020)
+- Indicate WPA and WIFI mode on OLED display
+- Correct sensor totals in Webserver overview.
+- Change delays for GPS and other internal sensors, and repair internal 
+  sensors to make sure we do not miss sensor messages
+- Changed the MONITOR part to a circular buffer to save time when filling buffer
+
 Features release 6.1.8 (January 21, 2020)
 - Repair wifimanager compile for ESP8266, and make it work for ESP8266
 - Substitues _DUSB by _MONITOR in a lot of cases

+ 50 - 29
ESP-sc-gway/ESP-sc-gway.ino

@@ -65,11 +65,19 @@ extern "C" {
 // ----------- Specific ESP32 stuff --------------
 #if defined (ARDUINO_ARCH_ESP32) || defined(ESP32)
 #	define ESP32_ARCH 1
-#	include <esp_wifi.h>
-#	include <WiFi.h>
+
+//#	include <esp_wifi.h>
+//#	include <WiFi.h>
 #	include <ESPmDNS.h>
 #	include <SPIFFS.h>
 
+#	if _WIFIMANAGER==1
+#		define ESP_getChipId()   ((uint32_t)ESP.getEfuseMac())
+#		include <ESP_WiFiManager.h>							// Library for ESP WiFi config through an AP
+//#		include <WebServer.h>
+//#		include <HttpClient.h>
+#	endif //_WIFIMANAGER
+
 #	if A_SERVER==1
 #		include <ESP32WebServer.h>							// Dedicated Webserver for ESP32
 #		include <Streaming.h>          						// http://arduiniana.org/libraries/streaming/
@@ -81,13 +89,6 @@ extern "C" {
 #		include <ArduinoOTA.h>
 #	endif //A_OTA
 
-#	if _WIFIMANAGER==1
-#		define ESP_getChipId()   ((uint32_t)ESP.getEfuseMac())
-#		include <ESP_WiFiManager.h>							// Library for ESP WiFi config through an AP
-//#		include <WebServer.h>						
-//#		include <HttpClient.h>
-#	endif //_WIFIMANAGER
-
 
 // ----------- Specific ESP8266 stuff --------------
 #elif defined(ARDUINO_ARCH_ESP8266)
@@ -164,7 +165,7 @@ char description[64]= _DESCRIPTION;							// used for free form description
 
 IPAddress ntpServer;										// IP address of NTP_TIMESERVER
 IPAddress ttnServer;										// IP Address of thethingsnetwork server
-IPAddress thingServer;
+IPAddress thingServer;										// Only if we use a second (backup) server
 
 WiFiUDP Udp;
 
@@ -190,9 +191,10 @@ uint32_t pullTime = 0;										// last time we sent a pull_data request to serv
 #endif
 
 // Init the indexes of the data we display on the webpage
-int16_t iMoni=0;
-int16_t iSeen=0;
-int16_t iSens=0;
+// We use this for circular buffers
+uint16_t iMoni=0;
+uint16_t iSeen=0;
+uint16_t iSens=0;
 
 // volatile bool inSPI This initial value of mutex is to be free,
 // which means that its value is 1 (!)
@@ -277,6 +279,11 @@ void setup() {
 		Serial.flush();
 #	endif //_DUSB
 
+
+#	if OLED>=1
+		init_oLED();										// When done display "STARTING" on OLED
+#	endif //OLED
+
 #	if _GPS==1
 		// Pins are defined in LoRaModem.h together with other pins
 		sGps.begin(9600, SERIAL_8N1, GPS_TX, GPS_RX);			// PIN 12-TX 15-RX
@@ -295,6 +302,7 @@ void setup() {
 		if (pdebug & P_MAIN) {
 			mPrint("SPIFFS.begin: not found, formatting");
 		}
+		msg_oLED("FORMAT");
 		SPIFFS.format();
 		delay(500);
 		initConfig(&gwayConfig);
@@ -302,6 +310,7 @@ void setup() {
 	
 	// If we set SPIFFS_FORMAT in 
 #	if _SPIFFS_FORMAT>=1
+	msg_oLED("FORMAT");
 	SPIFFS.format();										// Normally disabled. Enable only when SPIFFS corrupt
 	delay(500);
 	initConfig(&gwayConfig);
@@ -310,11 +319,10 @@ void setup() {
 	}
 #	endif //_SPIFFS_FORMAT>=1
 
-#if _MONITOR>=1
-	initMonitor(monitor);
-#endif
-
 #	if _MONITOR>=1
+		msg_oLED("MONITOR");
+		initMonitor(monitor);
+		
 #		if defined CFG_noassert
 			mPrint("No Asserts");
 #		else
@@ -343,17 +351,20 @@ void setup() {
 #		endif	
 	};							
 
-#	if OLED>=1
-		init_oLED();										// When done display "STARTING" on OLED
-#	endif //OLED
-
 	delay(500);
 	yield();
 
 #	if _WIFIMANAGER==1
+	msg_oLED("WIFIMGR");
+#	if MONITOR>=1
+		mPrint("setup:: WiFiManager");
+#	endif
+	delay(500);
+	
 	wifiMgr();
 #	endif //_WIFIMANAGER
 
+	msg_oLED("WIFI STA");
 	WiFi.mode(WIFI_STA);									// WiFi settings for connections
 	WiFi.setAutoConnect(true);
 	WiFi.macAddress(MAC_array);
@@ -365,7 +376,7 @@ void setup() {
 #	endif //_MONITOR
 
 
-	// Setup WiFi UDP connection. Give it some time and retry x times.. '0' means try forever
+	// Setup WiFi UDP connection. Give it some time and retry x times. '0' means try forever
 	while (WlanConnect(0) <= 0) {
 #		if _MONITOR>=1
 		if ((debug>=0) && (pdebug & P_MAIN)) {
@@ -385,12 +396,12 @@ void setup() {
 #	if defined(ESP32_ARCH)
 		// ESP32
 		sprintf(hostname, "%s%02x%02x%02x", "esp32-", MAC_array[3], MAC_array[4], MAC_array[5]);
-		WiFi.setHostname( hostname );
+		WiFi.setHostname(hostname);
 		MDNS.begin(hostname);
 #	else
 		//ESP8266
 		sprintf(hostname, "%s%02x%02x%02x", "esp8266-", MAC_array[3], MAC_array[4], MAC_array[5]);
-		wifi_station_set_hostname( hostname );
+		wifi_station_set_hostname(hostname);
 #	endif	//ESP32_ARCH
 
 #	if _MONITOR>=1
@@ -452,6 +463,7 @@ void setup() {
     // display results of getting hardware address
 	//
 #	if _MONITOR>=1
+	if (debug>=0) {
 		String response= "Gateway ID: ";
 		printHexDigit(MAC_array[0], response);
 		printHexDigit(MAC_array[1], response);
@@ -465,9 +477,11 @@ void setup() {
 		response += ", Listening at SF" + String(sf) + " on ";
 		response += String((double)freqs[gwayConfig.ch].upFreq/1000000) + " MHz.";
 		mPrint(response);
+	}
 #	endif //_MONITOR
 
 	// ---------- TIME -------------------------------------
+	msg_lLED("GET TIME",".");
 	ntpServer = resolveHost(NTP_TIMESERVER, 15);
 	if (ntpServer.toString() == "0:0:0:0")	{					// MMM Experimental
 #		if _MONITOR>=1
@@ -483,11 +497,13 @@ void setup() {
 		setupTime();											// Set NTP time host and interval
 		
 #	else //NTP_INTR
+	{
 		// If not using the standard libraries, do manual setting
 		// of the time. This method works more reliable than the 
 		// interrupt driven method.
-	
+		String response = ".";
 		while (timeStatus() == timeNotSet) {					// time still 1/1/1970 and 0:00 hrs
+
 			time_t newTime;
 			if (getNtpTime(&newTime)<=0) {
 #				if _MONITOR>=1
@@ -495,9 +511,13 @@ void setup() {
 					mPrint("setup:: ERROR Time not set (yet). Time="+String(newTime) );
 				}
 #				endif //_MONITOR
+				response += ".";
+				msg_lLED("GET TIME",response);
 				delay(800);
 				continue;
 			}
+			response += ".";
+			msg_lLED("GET TIME",response);
 			delay(1000);
 			setTime(newTime);
 		}
@@ -513,6 +533,7 @@ void setup() {
 #		endif //_MONITOR
 
 		writeGwayCfg(CONFIGFILE, &gwayConfig );
+	}
 #	endif //NTP_INTR
 
 	delay(100);
@@ -731,8 +752,8 @@ void loop ()
 			}
 		}
 	}
-	
-	yield();					// on 26/12/2017
+
+	yield();												// on 26/12/2017
 
 	// stat PUSH_DATA message (*2, par. 4)
 	//	
@@ -754,10 +775,10 @@ void loop ()
 		if (gwayConfig.isNode) {
 			// Give way to internal some Admin if necessary
 			yield();
-			
+
 			// If the 1ch gateway is a sensor itself, send the sensor values
 			// could be battery but also other status info or sensor info
-		
+
 			if (sensorPacket() < 0) {
 #				if _MONITOR>=1
 				if ((debug>=1) || (pdebug & P_MAIN)) {

+ 1 - 1
ESP-sc-gway/LICENSE.md

@@ -1,6 +1,6 @@
 MIT License
 
-Copyright (c) 2016, 2017, 2018, 2019 Maarten Westenberg (mw12554@hotmail.com)
+Copyright (c) 2016-2020 Maarten Westenberg (mw12554@hotmail.com)
 
 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal

+ 1 - 1
ESP-sc-gway/LICENSE.txt

@@ -1,6 +1,6 @@
 MIT License
 
-Copyright (c) 2016-2019 Maarten Westenberg
+Copyright (c) 2016-2020 Maarten Westenberg
 
 Permission is hereby granted, free of charge, to any person obtaining a copy
 of this software and associated documentation files (the "Software"), to deal

+ 2 - 1
ESP-sc-gway/_loraFiles.ino

@@ -25,8 +25,9 @@
 int initMonitor(struct moniLine *monitor) 
 {
 	for (int i=0; i< _MAXMONITOR; i++) {
-		monitor[i].txt="";
+		monitor[i].txt= "-";						// Make all lines empty
 	}
+	iMoni=0;										// Init the index
 	return(1);
 }
 

+ 33 - 8
ESP-sc-gway/_oLED.ino

@@ -39,7 +39,7 @@ void init_oLED()
 	// Initialising the UI will init the display too.
 	display.init();
 	delay(100);
-	//display.begin(SSD1306_SWITCHCAPVCC, OLED_ADDR, FALSE)
+
 	display.flipScreenVertically();
 	display.setFont(ArialMT_Plain_24);
 	display.setTextAlignment(TEXT_ALIGN_LEFT);
@@ -48,11 +48,14 @@ void init_oLED()
 }
 
 // --------------------------------------------------------------------
-// Activate the OLED
+// Activate the OLED. Always print the same info.
+// These are 4 fields:
+// SSID, IP, ID, 
 //
 // --------------------------------------------------------------------
 void acti_oLED() 
 {
+#	if OLED>=1
 	// Initialising the UI will init the display too.
 	display.clear();
 	
@@ -71,7 +74,7 @@ void acti_oLED()
 #endif
 
 	display.display();
-	
+#endif // OLED
 	delay(4000);
 }
 
@@ -80,15 +83,37 @@ void acti_oLED()
 // Note: The whole message must fit in the buffer
 //
 // --------------------------------------------------------------------
-void msg_oLED(String tim, String sf) {
+void msg_oLED(String mesg) 
+{
+#if OLED>=1
     display.clear();
-    display.setFont(ArialMT_Plain_16);
-    display.setTextAlignment(TEXT_ALIGN_LEFT);
+
+	display.flipScreenVertically();
+	display.setFont(ArialMT_Plain_24);
+	display.setTextAlignment(TEXT_ALIGN_LEFT);
+	display.drawString(0, 24, String(mesg));
+
+    display.display();
+	yield();
+#endif //OLED
+}
+
+// Print a smaller OLED message consisting of two strings
+
+void msg_lLED(String mesg, String mesg2) 
+{
+#if OLED>=1
+    display.clear();
+
+	display.flipScreenVertically();
+	display.setFont(ArialMT_Plain_16);
+	display.setTextAlignment(TEXT_ALIGN_LEFT);
+	display.drawString(0, 8, String(mesg));
+	display.drawString(0, 36, String(mesg2));
 	
-	display.drawString(0, 48, "LEN: " );
-//    display.drawString(40, 48, String((int)messageLength) );
     display.display();
 	yield();
+#endif //OLED
 }
 
 // --------------------------------------------------------------------

+ 51 - 43
ESP-sc-gway/_sensor.ino

@@ -77,37 +77,19 @@ static int LoRaSensors(uint8_t *buf) {
 #		error "Only define ONE encoding in configNode.h, _LOCDE or _RAW"
 #		endif
 
+		String response="";
 		uint8_t tchars = 1;
-		buf[0] = 0x86;				// 134; User code <lCode + len==3 + Parity
+		buf[0] = 0x86;								// 134; User code <lCode + len==3 + Parity
 		
 #		if _MONITOR>=1
 		if (debug>=0) {
-			mPrint("LoRaSensors:: ");
+			response += "LoRaSensors:: ";
 		}
 #		endif //_MONITOR
 
-#		if _BATTERY==1
-#			if defined(ARDUINO_ARCH_ESP8266) || defined(ESP32)
-				// For ESP there is no standard battery library
-				// What we do is to measure GPIO35 pin which has a 100K voltage divider
-				pinMode(35, INPUT);
-				float volts=3.3 * analogRead(35) / 4095 * 2;	// T_Beam connects to GPIO35
-#			else
-				// For ESP8266 no sensor defined
-				float volts=0;
-#			endif // ARDUINO_ARCH_ESP8266 || ESP32
-#			if _MONITOR>=1
-			if ((debug>=1) && ( pdebug & P_MAIN )){
-				mPrint("Battery lcode="+String(volts));
-			}
-#			endif //_MONITOR
-
-			tchars += lcode.eBattery(volts, buf + tchars);
-#		endif //_BATTERY
-
 		// GPS sensor is the second server we check for
 #		if _GPS==1
-			smartDelay(1000);
+			smartDelay(10);							// Use GPS to return fast!
 			if (millis() > 5000 && gps.charsProcessed() < 10) {
 #				if _MONITOR>=1
 					mPrint("ERROR: No GPS data received: check wiring");
@@ -120,21 +102,12 @@ static int LoRaSensors(uint8_t *buf) {
 
 			// Use lcode to code messages to server
 #			if _MONITOR>=1
-			if ((debug>=1) && ( pdebug & P_MAIN )){
-				mPrint("gps lcode:: lat="+String(gps.location.lat())+", lng="+String(gps.location.lng())+", alt="+String(gps.altitude.feet()/3.2808)+", sats="+String(gps.satellites.value()) );
+			if ((debug>=1) && (pdebug & P_MAIN)){
+				response += ", Gps lcode:: lat="+String(gps.location.lat())+", lng="+String(gps.location.lng())+", alt="+String(gps.altitude.feet()/3.2808)+", sats="+String(gps.satellites.value());
 			}
 #			endif //_MONITOR
 			tchars += lcode.eGpsL(gps.location.lat(), gps.location.lng(), gps.altitude.value(), gps.satellites.value(), buf + tchars);
 #		endif //_GPS
-		// If all sensor data is encoded, we encode the buffer
-		lcode.eMsg(buf, tchars);								// Fill byte 0 with bytecount and Parity
-
-
-// Second encoding option is RAW format. 
-// We do not use the lcode format but write all the values to the output
-// buffer and we need to get them in sequence out off the buffer.
-#	elif defined(_RAW)
-		uint8_t tchars = 0;
 
 #		if _BATTERY==1
 #			if defined(ARDUINO_ARCH_ESP8266) || defined(ESP32)
@@ -146,18 +119,33 @@ static int LoRaSensors(uint8_t *buf) {
 				// For ESP8266 no sensor defined
 				float volts=0;
 #			endif // ARDUINO_ARCH_ESP8266 || ESP32
-			memcpy((buf+tchars), &volts, sizeof(float)); tchars += sizeof(float);
-			
 #			if _MONITOR>=1
-			if ((debug>=1) && ( pdebug & P_MAIN )){
-				mPrint("Battery raw="+String(volts));
+			if ((debug>=1) && (pdebug & P_MAIN)){
+				response += "Battery lcode="+String(volts);
 			}
 #			endif //_MONITOR
+
+			tchars += lcode.eBattery(volts, buf + tchars);
 #		endif //_BATTERY
 
+
+		// If all sensor data is encoded, we encode the buffer
+		lcode.eMsg(buf, tchars);								// Fill byte 0 with bytecount and Parity
+		
+#		if _MONITOR>=1
+			mPrint(response);
+#		endif //_MONITOR
+
+// Second encoding option is RAW format. 
+//
+// We do not use the lcode format but write all the values to the output
+// buffer and we need to get them in sequence out off the buffer.
+#	elif defined(_RAW)
+		uint8_t tchars = 0;
+
 		// GPS sensor is the second server we check for
 #		if _GPS==1
-			smartDelay(1000);
+			smartDelay(10);
 			if (millis() > 5000 && gps.charsProcessed() < 10) {
 #				if _MONITOR>=1
 					mPrint("ERROR: No GPS data received: check wiring");
@@ -180,6 +168,25 @@ static int LoRaSensors(uint8_t *buf) {
 			memcpy((buf+tchars), &alt, sizeof(double)); tchars += sizeof(double);
 #		endif //_GPS
 
+#		if _BATTERY==1
+#			if defined(ARDUINO_ARCH_ESP8266) || defined(ESP32)
+				// For ESP there is no standard battery library
+				// What we do is to measure GPIO35 pin which has a 100K voltage divider
+				pinMode(35, INPUT);
+				float volts=3.3 * analogRead(35) / 4095 * 2;	// T_Beam connects to GPIO35
+#			else
+				// For ESP8266 no sensor defined
+				float volts=0;
+#			endif // ARDUINO_ARCH_ESP8266 || ESP32
+			memcpy((buf+tchars), &volts, sizeof(float)); tchars += sizeof(float);
+			
+#			if _MONITOR>=1
+			if ((debug>=1) && ( pdebug & P_MAIN )){
+				mPrint("Battery raw="+String(volts));
+			}
+#			endif //_MONITOR
+#		endif //_BATTERY
+
 
 // If neither _LCODE or _RAW is defined this is an error
 #	else
@@ -595,11 +602,12 @@ int sensorPacket() {
 	int buff_index = buildPacket(tmst, buff_up, LUP, true);
 	
 	frameCount++;
-    statc.msg_ttl++;				// XXX Should we count sensor messages as well?
-	switch(gwayConfig.ch) {
-		case 0: statc.msg_ttl_0++; break;
-		case 1: statc.msg_ttl_1++; break;
-		case 2: statc.msg_ttl_2++; break;
+	statc.msg_ttl++;					// XXX Should we count sensor messages as well?
+	statc.msg_sens++;
+	switch(gwayConfig.ch) {			// MMM remove when possible
+		case 0: statc.msg_sens_0++; break;
+		case 1: statc.msg_sens_1++; break;
+		case 2: statc.msg_sens_2++; break;
 	}
 	
 	// In order to save the memory, we only write the framecounter

+ 1 - 7
ESP-sc-gway/_udpSemtech.ino

@@ -186,11 +186,6 @@ int readUdp(int packetSize)
 #if _MONITOR>=1
 			if (( debug>=2) && (pdebug & P_MAIN )) {
 				mPrint("M PKT_PUSH_ACK:: size="+String(packetSize)+" From "+String(remoteIpNo.toString())); 
-//				Serial.print(F(", port ")); 
-//				Serial.print(remotePortNo);
-//				Serial.print(F(", token: "));
-//				Serial.println(token, HEX);
-//				Serial.println();
 			}
 #endif //_MONITOR
 		break;
@@ -206,7 +201,7 @@ int readUdp(int packetSize)
 		case PKT_PULL_RESP:	// 0x03 DOWN
 #			if _MONITOR>=1
 			if (( debug>=0 ) && ( pdebug & P_MAIN )) {
-				mPrint("readUdp:: PKT_PULL_RESP received");
+				mPrint("readUdp:: PKT_PULL_RESP received from IP="+String(remoteIpNo.toString()));
 			}
 #			endif //_MONITOR
 //			lastTmst = micros();					// Store the tmst this package was received
@@ -228,7 +223,6 @@ int readUdp(int packetSize)
 			buff[0]=buff_down[0];
 			buff[1]=buff_down[1];
 			buff[2]=buff_down[2];
-			//buff[3]=PKT_PULL_ACK;					// Pull request/Change of Mogyi
 			buff[3]=PKT_TX_ACK;
 			buff[4]=MAC_array[0];
 			buff[5]=MAC_array[1];

+ 12 - 14
ESP-sc-gway/_utils.ino

@@ -77,6 +77,7 @@ void printHexDigit(uint8_t digit, String & response)
 // Print to the monitor console.
 // This function is used all over the gateway code as a substite for USB debug code.
 // It allows webserver users to view printed/debugging code.
+// With initMonitor() we init the index iMoni=0;
 //
 // Parameters:
 //	txt: The text to be printed.
@@ -88,31 +89,28 @@ void mPrint(String txt)
 	
 #	if _DUSB>=1
 		Serial.println(txt);
-		//Serial.println(F(txt));
 		if (debug>=2) Serial.flush();
 #	endif //_DUSB
 
 #	if _MONITOR>=1
 	time_t tt = now();
-	
-	// MMM perhaps better make this a circular buffer
-	for (int i=_MAXMONITOR; i>0; i--) {		// Do only for values present....
-		monitor[i]= monitor[i-1];
-	}
-	
-	monitor[0].txt  = String(day(tt))	+ "-";
-	monitor[0].txt += String(month(tt))	+ "-";
-	monitor[0].txt += String(year(tt))	+ " ";
+
+	monitor[iMoni].txt  = String(day(tt))	+ "-";
+	monitor[iMoni].txt += String(month(tt))	+ "-";
+	monitor[iMoni].txt += String(year(tt))	+ " ";
 	
 	uint8_t _hour   = hour(tt);
 	uint8_t _minute = minute(tt);
 	uint8_t _second = second(tt);
 
-	if (_hour   < 10) monitor[0].txt += "0"; monitor[0].txt += String( _hour )+ ":";
-	if (_minute < 10) monitor[0].txt += "0"; monitor[0].txt += String(_minute) + ":";
-	if (_second < 10) monitor[0].txt += "0"; monitor[0].txt += String(_second) + "- ";
+	if (_hour   < 10) monitor[iMoni].txt += "0"; monitor[iMoni].txt += String( _hour )+ ":";
+	if (_minute < 10) monitor[iMoni].txt += "0"; monitor[iMoni].txt += String(_minute) + ":";
+	if (_second < 10) monitor[iMoni].txt += "0"; monitor[iMoni].txt += String(_second) + "- ";
+	
+	monitor[iMoni].txt += String(txt);
 	
-	monitor[0].txt += String(txt);
+	// Use the circular buffer to increment the index
+	iMoni = (iMoni+1) % _MAXMONITOR	;				// And goto 0 when skipping over _MAXMONITOR
 	
 #	endif //_MONITOR
 	return;

+ 40 - 22
ESP-sc-gway/_wwwServer.ino

@@ -396,9 +396,6 @@ static void setVariables(const char *cmd, const char *arg) {
 static void openWebPage()
 {
 	++gwayConfig.views;									// increment number of views
-#if A_REFRESH==1
-	//server.client().stop();							// Experimental, stop webserver in case something is still running!
-#endif
 	String response="";	
 
 	server.sendHeader("Cache-Control", "no-cache, no-store, must-revalidate");
@@ -611,7 +608,7 @@ static void gatewaySettings()
 	response +="<td class=\"cell\" colspan=\"2\">";
 	response +=frameCount;
 	response +="</td><td colspan=\"2\" style=\"border: 1px solid black;\">";
-	response +="<button><a href=\"/FCNT\">RESET</a></button></td>";
+	response +="<button><a href=\"/FCNT\">RESET   </a></button></td>";
 	response +="</tr>";
 	
 	bg = " background-color: ";
@@ -653,25 +650,27 @@ static void gatewaySettings()
 	response +="</td><td></td></tr>";
 #endif //_WIFIMANAGER
 
-	// Update Firmware all statistics
+#if _UPDFIRMWARE==1
+	// Update Firmware
 	response +="<tr><td class=\"cell\">Update Firmware</td><td colspan=\"2\"></td>";
 	response +="<td class=\"cell\" colspan=\"2\" class=\"cell\"><a href=\"/UPDATE=1\"><button>UPDATE</button></a></td></tr>";
+#endif //_UPDFIRMWARE
 
 	// Format the Filesystem
 	response +="<tr><td class=\"cell\">Format SPIFFS</td>";
 	response +=String() + "<td class=\"cell\" colspan=\"2\" >"+""+"</td>";
-	response +="<td colspan=\"2\" class=\"cell\"><input type=\"button\" value=\"FORMAT\" onclick=\"ynDialog(\'Do you really want to format?\',\'FORMAT\')\" /></td></tr>";
+	response +="<td style=\"width:30px;\" colspan=\"2\" class=\"cell\"><input type=\"button\" value=\"FORMAT\" onclick=\"ynDialog(\'Do you really want to format?\',\'FORMAT\')\" /></td></tr>";
 
 	// Reset all statistics
 #if _STATISTICS >= 1
 	response +="<tr><td class=\"cell\">Statistics</td>";
 	response +=String() + "<td class=\"cell\" colspan=\"2\" >"+statc.resets+"</td>";
-	response +="<td colspan=\"2\" class=\"cell\"><input type=\"button\" value=\"RESET\" onclick=\"ynDialog(\'Do you really want to reset statistics?\',\'RESET\')\" /></td></tr>";
+	response +="<td style=\"width:30px;\" colspan=\"2\" class=\"cell\"><input type=\"button\" value=\"RESET   \" onclick=\"ynDialog(\'Do you really want to reset statistics?\',\'RESET\')\" /></td></tr>";
 
 	// Reset Node
 	response +="<tr><td class=\"cell\">Boots and Resets</td>";
 	response +=String() + "<td class=\"cell\" colspan=\"2\" >"+gwayConfig.boots+"</td>";
-	response +="<td colspan=\"2\" class=\"cell\"><input type=\"button\" value=\"BOOT\" onclick=\"ynDialog(\'Do you want to reset boots?\',\'BOOT\')\" /></td></tr>";
+	response +="<td style=\"width:30px;\" colspan=\"2\" class=\"cell\" ><input type=\"button\" value=\"BOOT    \" onclick=\"ynDialog(\'Do you want to reset boots?\',\'BOOT\')\" /></td></tr>";
 #endif //_STATISTICS
 	
 	response +="</table>";
@@ -689,8 +688,9 @@ static void gatewaySettings()
 static void statisticsData()
 {
 	String response="";
-
-	// Header
+	//
+	// Header Row
+	//
 	response +="<h2>Package Statistics</h2>";
 	response +="<table class=\"config_table\">";
 	response +="<tr><th class=\"thead\">Counter</th>";
@@ -723,7 +723,18 @@ static void statisticsData()
 #	endif //_STATISTICS==3
 	response +="<td class=\"cell\">" + String(statc.msg_ttl) + "</td>";
 	response +="<td class=\"cell\">" + String((statc.msg_ttl*3600)/(now() - startTime)) + "</td></tr>";
-		
+
+#	if _GATEWAYNODE==1
+		response +="<tr><td class=\"cell\">Packages Internal Sensor</td>";
+#		if	 _STATISTICS == 3
+			response +="<td class=\"cell\">" + String(statc.msg_sens_0) + "</td>";
+			response +="<td class=\"cell\">" + String(statc.msg_sens_1) + "</td>";
+			response +="<td class=\"cell\">" + String(statc.msg_sens_2) + "</td>";
+#		endif //_STATISTICS==3
+		response +="<td class=\"cell\">" + String(statc.msg_sens) + "</td>";
+		response +="<td class=\"cell\">" + String((statc.msg_sens*3600)/(now() - startTime)) + "</td></tr>";
+#	endif //_GATEWAYNODE
+
 	response +="<tr><td class=\"cell\">Packages Uplink OK </td>";
 #if	 _STATISTICS == 3
 		response +="<td class=\"cell\">" + String(statc.msg_ok_0) + "</td>";
@@ -731,7 +742,7 @@ static void statisticsData()
 		response +="<td class=\"cell\">" + String(statc.msg_ok_2) + "</td>";
 #	endif //_STATISTICS==3
 	response +="<td class=\"cell\">" + String(statc.msg_ok) + "</td>";
-	response +="<td class=\"cell\"></td></tr>";
+	response +="<td class=\"cell\">" + String((statc.msg_ok*3600)/(now() - startTime)) + "</td></tr>";
 		
 
 	// Provide a table with all the SF data including percentage of messsages
@@ -1056,20 +1067,20 @@ int monitorData()
 		response +="<th class=\"thead\">Monitor Console</th>";
 		response +="</tr>";
 		
-
-		for (int i=0; i<_MAXMONITOR; i++) {
-			if (monitor[i].txt == "") {
+		for (int i= iMoni-1+_MAXMONITOR; i>=iMoni; i--) {
+			if (monitor[i % _MAXMONITOR].txt == "-") {		// If equal to init value '-'
 				break;
 			}
-			// DISPLAY line
 			response +="<tr><td class=\"cell\">" ;
-			response += String(monitor[i].txt);
+			response += String(monitor[i % _MAXMONITOR].txt);
 			response += "</td></tr>";
+
 		}
+		
 		response +="</table>";
 		server.sendContent(response);
 	}
-#	endif
+#	endif //_MONITOR
 }
 
 
@@ -1286,7 +1297,7 @@ void setupWWW()
 	// Format the filesystem
 	server.on("/FORMAT", []() {
 		Serial.print(F("FORMAT ..."));
-		
+		msg_oLED("FORMAT");		
 		SPIFFS.format();							// Normally not used. Use only when SPIFFS corrupt
 		initConfig(&gwayConfig);					// Well known values
 		writeConfig( CONFIGFILE, &gwayConfig);
@@ -1309,17 +1320,24 @@ void setupWWW()
 		statc.msg_ttl = 0;						// Reset ALL package statistics
 		statc.msg_ok = 0;
 		statc.msg_down = 0;
+		statc.msg_sens = 0;
 		
 #if _STATISTICS >= 3
 		statc.msg_ttl_0 = 0;
 		statc.msg_ttl_1 = 0;
 		statc.msg_ttl_2 = 0;
+		
 		statc.msg_ok_0 = 0;
 		statc.msg_ok_1 = 0;
 		statc.msg_ok_2 = 0;
+		
 		statc.msg_down_0 = 0;
 		statc.msg_down_1 = 0;
-		statc.msg_down_2 = 0;	
+		statc.msg_down_2 = 0;
+
+		statc.msg_sens_0 = 0;
+		statc.msg_sens_1 = 0;
+		statc.msg_sens_2 = 0;
 #endif
 
 #	if _STATISTICS >= 1
@@ -1560,7 +1578,7 @@ void setupWWW()
 #if _GATEWAYNODE==1
 		gwayConfig.isNode =(bool)1;
 		writeGwayCfg(CONFIGFILE, &gwayConfig );	// Save configuration to file
-#endif
+#endif //_GATEWAYNODE
 		server.sendHeader("Location", String("/"), true);
 		server.send ( 302, "text/plain", "");
 	});
@@ -1568,7 +1586,7 @@ void setupWWW()
 #if _GATEWAYNODE==1
 		gwayConfig.isNode =(bool)0;
 		writeGwayCfg(CONFIGFILE, &gwayConfig );	// Save configuration to file
-#endif
+#endif //_GATEWAYNODE
 		server.sendHeader("Location", String("/"), true);
 		server.send ( 302, "text/plain", "");
 	});

+ 11 - 11
ESP-sc-gway/configGway.h

@@ -3,7 +3,7 @@
 
 // Specify the correct version and date of your gateway here.
 // Normally it is provided with the GitHub version
-#define VERSION "V.6.1.8.E.EU868; 200121M"
+#define VERSION "V.6.2.0.E.EU868; 200129b"
 //
 // Based on work done by Thomas Telkamp for Raspberry PI 1ch gateway and many others.
 // Contibutions of Dorijan Morelj and Andreas Spies for OLED support.
@@ -39,11 +39,8 @@
 #define _SPIFFS_FORMAT 0
 
 
-// Define the CLASS mode of the gateway
-// A: Baseline Class
-// B: Beacon/Battery Class
-// C: Continuous Listen Class
-#define _CLASS "A"
+// Allows configuration through WifiManager AP setup. Must be 0 or 1					
+#define _WIFIMANAGER 0
 
 
 // Debug message will be put on Serial is this one is set.
@@ -80,7 +77,14 @@
 // See https://www.thethingsnetwork.org/docs/lorawan/frequency-plans.html
 #define EU863_870 1
  
- 
+
+// Define the CLASS mode of the gateway
+// A: Baseline Class
+// B: Beacon/Battery Class
+// C: Continuous Listen Class
+#define _CLASS "A"
+
+
 // Define whether to use the old Semtech gateway API, which is still supported by TTN,
 // but is more lightweight than the new TTN tcp based protocol.
 // NOTE: Only one of the two should be defined! TTN Router project has stopped
@@ -159,10 +163,6 @@
 #define _RX2_SF 9
 
 
-// Allows configuration through WifiManager AP setup. Must be 0 or 1					
-#define _WIFIMANAGER 0
-
-
 // This section defines whether we use the gateway as a repeater
 // For his, we use another output channel as the channel (default==0) we are 
 // receiving the messages on.

+ 1 - 1
ESP-sc-gway/loraFiles.h

@@ -1,5 +1,5 @@
 // 1-channel LoRa Gateway for ESP8266
-// Copyright (c) 2016, 2017, 2018, 2019 Maarten Westenberg version for ESP8266
+// Copyright (c) 2016-2020 Maarten Westenberg version for ESP mcu's
 //
 // 	based on work done by Thomas Telkamp for Raspberry PI 1ch gateway
 //	and many others.

+ 9 - 11
ESP-sc-gway/loraModem.h

@@ -297,26 +297,24 @@ struct stat_c {
 	uint32_t msg_ok;
 	uint32_t msg_ttl;
 	uint32_t msg_down;
+	uint32_t msg_sens;
 
 #if _STATISTICS >= 2						// Only if we explicitly set it higher	
-	uint32_t sf7;							// Spreading factor 7 statistics/Count
-	uint32_t sf8;							// Spreading factor 8
-	uint32_t sf9;							// Spreading factor 9
-	uint32_t sf10;							// Spreading factor 10
-	uint32_t sf11;							// Spreading factor 11
-	uint32_t sf12;							// Spreading factor 12
+	uint32_t sf7, sf8, sf9;					// Spreading factor 7, 8, 9 statistics/Count
+	uint32_t sf10, sf11, sf12;				// Spreading factor 10, 11, 12
 	
 	// If _STATISTICS is 3, we add statistics about the channel 
 	// When only one channel is used, we normally know the spread of
 	// statistics, but when HOP mode is selected we migth want to add this info
 #if _STATISTICS >=3
-	uint32_t msg_ok_0, msg_ok_1, msg_ok_2;
-	uint32_t msg_ttl_0, msg_ttl_1, msg_ttl_2;
+	uint32_t msg_ok_0,   msg_ok_1,   msg_ok_2;
+	uint32_t msg_ttl_0,  msg_ttl_1,  msg_ttl_2;
 	uint32_t msg_down_0, msg_down_1, msg_down_2;
+	uint32_t msg_sens_0, msg_sens_1, msg_sens_2;
 
-	uint32_t sf7_0, sf7_1, sf7_2;
-	uint32_t sf8_0, sf8_1, sf8_2;
-	uint32_t sf9_0, sf9_1, sf9_2;
+	uint32_t  sf7_0,  sf7_1,  sf7_2;
+	uint32_t  sf8_0,  sf8_1,  sf8_2;
+	uint32_t  sf9_0,  sf9_1,  sf9_2;
 	uint32_t sf10_0, sf10_1, sf10_2;
 	uint32_t sf11_0, sf11_1, sf11_2;
 	uint32_t sf12_0, sf12_1, sf12_2;

+ 6 - 4
README.md

@@ -1,7 +1,7 @@
 # Single Channel LoRaWAN Gateway
 
-Version 6.1.8, 
-Data: January 21, 2020  
+Version 6.2.0, 
+Data: January 29, 2020  
 Author: M. Westenberg (mw12554@hotmail.com)  
 Copyright: M. Westenberg (mw12554@hotmail.com)  
 
@@ -258,11 +258,13 @@ to configure the gatewayat run-time and inspects its behaviour. It also provides
 The A_REFRESH parameter defines whether the webserver should renew every X seconds.
 
  \#define A_SERVER 1				// Define local WebServer only if this define is set  
- \#define A_REFRESH 0				// Will the webserver refresh or not?  
+ \#define A_REFRESH 1				// is the webserver enabled to refresh yes/no?  (yes is OK)
  \#define A_SERVERPORT 80			// local webserver port  
  \#define A_MAXBUFSIZE 192			// Must be larger than 128, but small enough to work  
 
- The A_REFRESH parameter determines the refresh frequency of the webserver.  
+ The A_REFRESH parameter defines whether or not we can set the refresh yes/no setting in the webbrowser. 
+ The setting in the webbrowser is normally put on "no" as a default, but we can leave the define on
+ "1" to enabled that setting in the webbrowser.
  
 ### Strict LoRa behaviour
 

+ 1 - 1
TODO.md

@@ -1,6 +1,6 @@
 # Single Channel LoRaWAN Gateway
 
-Last Updated: December 29, 2019	  
+Last Updated: January 29, 2020	  
 Author: M. Westenberg (mw12554@hotmail.com)  
 Copyright: M. Westenberg (mw12554@hotmail.com)