Local server in node.js example


#21

Is there any output in the console of the webbrower?


#22

@Moors7 yes there is, the value is constantly updated but no output on the web


#23

I was thinking more along the lines of the developer console in your web browser, not the Particle Console :wink:
Try right-clicking and then selecting ‘inspect this page’. You should then see the developer tools with a tab for ‘console’. See if that has any output.


#24

Hahaha…i see.

It seems like it failed.

Can you kindly help with that?


#25

It appears these are two completely different subnets
Your first post mentions 192.168.43.xxx and the console complains about `192.168.137.xxx.
I guess that might be a point to start your search from :wink:


#27

Hi, I followed your example and it works.
Can you teach me how to get reading from SparkFun Humidity and Temperature Sensor Breakout - Si7021 and display them on localhost instead of accelerometer.
I have the working ino file for my Si7021 sensor which is using particle.variable to display data on google spreadsheet.but i dont know how can i convert my project to localhost like yours.


#28

You should only have to edit the sendData function, since that’s where the data is collected and transmitted. Everything else should remain the same I suppose.


#30

Hi, I have tried putting my code into send data function but i cant compile it… Do you mind providing me your email so that I can send you my code to have a look… and suggest me what I am doing wrong.
Thank you so much for your reply. I am very new to this and programming related stuff


#31

You can paste your code on the forums as well so others can take a look. Just make sure you format it so it’s readable.
What errors do you get when compiling?


#32
#include "SparkFun_Si7021_Breakout_Library.h"
#include "Adafruit_DHT.h"

#define DHTPIN 5
#define DHTTYPE DHT11

float Humidity_Si = 0;
float Temperature_Si = 0;
float Humidity_DHT = 0;
float Temperature_DHT = 0;
char resultstr[64]; //String to store the sensor temp
char humiditystr[64]; //String to store the sensor humidity
int Temperature =0;
int Humidity =0;
int power = A3;
int GND = A2;

//Create Instance of HTU21D or SI7021 temp and humidity sensor and MPL3115A2 barrometric sensor
DHT dht(DHTPIN, DHTTYPE);
Weather sensor;

//---------------------------------------------------------------
void setup()
{
    dht.begin();
    Serial.begin(9600);   // open serial over USB at 9600 baud
    pinMode(power, OUTPUT);
    pinMode(GND, OUTPUT);
    Particle.variable("Temperature", resultstr, STRING);
    Particle.variable("Humidity", humiditystr, STRING);
  //  Particle.variable("Temperature",Temperature);
  //  Particle.variable("Humidity",Humidity);
    digitalWrite(power, HIGH);
    digitalWrite(GND, LOW);

    //Initialize the I2C sensors and ping them
    sensor.begin();

}
//---------------------------------------------------------------
void loop()
{
    //Get readings from all sensors
    getWeather();
    getWeather01();
    delay(10000);
    getWeather();
    printInfo();
    getWeather01();
    printInfo01();
    delay(10000);

    if (Temperature_Si>10 and Humidity_Si>10 and Temperature_Si<100 and Humidity_Si<100)
    {
      getWeather();
      printInfo();
      delay(20000);
      getWeather();
      printInfo();
      delay(20000);
      getWeather();
      printInfo();
      delay(20000);
    }
    else
      {
        getWeather01();
        printInfo01();
        delay(20000);
        getWeather01();
        printInfo01();
        delay(20000);
        getWeather01();
        printInfo01();
        delay(20000);
      }
    //System.sleep(10);

  //if (Temperature_Si>10 and Humidity_Si>10 and Temperature_Si<100 and Humidity_Si<100)
  //     {System.sleep(SLEEP_MODE_DEEP, 60);}
  //if (Temperature_DHT>10 and Humidity_DHT>10 and Temperature_DHT<100 and Humidity_DHT<100)
  //   {System.sleep(SLEEP_MODE_DEEP, 60);}

}
//---------------------------------------------------------------
void getWeather()
{
  // Measure Relative Humidity from the HTU21D or Si7021
  Humidity_Si = sensor.getRH();
  Temperature_Si = sensor.getTempF();

  Humidity = sensor.getRH();
  Temperature = sensor.getTempF();
  char tempInChar[32];
  sprintf(tempInChar,"%0d.%d", (int)Temperature);
  sprintf(resultstr, "{\"t\":%s}", tempInChar);
  char humiInChar[32];
  sprintf(humiInChar,"%0d.%d", (int)Humidity);
  sprintf(humiditystr, "{\"t\":%s}", humiInChar);
  // Measure Temperature from the HTU21D or Si7021

  // Temperature is measured every time RH is requested.
  // It is faster, therefore, to read it from previous RH
  // measurement with getTemp() instead with readTemp()
}
void getWeather01()
{
  // Measure Relative Humidity from the HTU21D or Si7021
  Humidity_DHT = (dht.getHumidity())*1.8;
  // Measure Temperature from the HTU21D or Si7021
  Temperature_DHT = (((dht.getTempCelcius())*1.8)+32);

  Humidity = (dht.getHumidity())*1.8;
  Temperature = (((dht.getTempCelcius())*1.8)+32);
  char tempInChar[32];
  sprintf(tempInChar,"%0d.%d", (int)Temperature);
  sprintf(resultstr, "{\"t\":%s}", tempInChar);
  char humiInChar[32];
  sprintf(humiInChar,"%0d.%d", (int)Humidity);
  sprintf(humiditystr, "{\"t\":%s}", humiInChar);

  // Temperature is measured every time RH is requested.
  // It is faster, therefore, to read it from previous RH
  // measurement with getTemp() instead with readTemp()
}
//---------------------------------------------------------------
void printInfo()
{
//This function prints the weather data out to the default Serial Port

  Serial.print("TemperaturexSi:");
  Serial.print(Temperature_Si);
  Serial.print("F, ");
  Particle.publish("Temperature_Si", String(Temperature_Si)+"F", PRIVATE);
  //Particle.publish("Temperature", String(Temperaturex)+"F", PRIVATE);

  Serial.print("HumiditySi:");
  Serial.print(Humidity_Si);
  Serial.println("%");
  Particle.publish("Humidity_Si", String(Humidity_Si)+"%", PRIVATE);

  //Particle.publish("Humidity", String(Humidityx)+"%", PRIVATE);
}
void printInfo01()
{
//This function prints the weather data out to the default Serial Port

  Serial.print("TemperaturexDHT:");
  Serial.print(Temperature_DHT);
  Serial.print("F, ");
  Particle.publish("Temperature_DHT", String(Temperature_DHT)+"F", PRIVATE);
  //Particle.publish("Temperature", String(Temperaturex)+"F", PRIVATE);

  Serial.print("HumidityDHT:");
  Serial.print(Humidity_DHT);
  Serial.println("%");
  Particle.publish("Humidity_DHT", String(Humidity_DHT)+"%", PRIVATE);

  //Particle.publish("Humidity", String(Humidityx)+"%", PRIVATE);
}

Above is my code>>> With this, I can view my sensor reading on dashboard and also be able to send data to my google spreadsheet script. But my goal is to get sensor data on my local server without going through cloud and display the data reading on simple web page. Thank you.


#33

And how did you try to combine that with Rick’s code?
(Do try to use non-blocking delays)


#34

Hi , Below is my code combined with Rick’s code. Now, I can complie and upload into my photon but im not receiving any data on localweb page, please help me to have a look and advise me.

#include "Particle.h"
#include "SparkFun_Si7021_Breakout_Library.h"
#include "Adafruit_DHT.h"
#define DHTPIN 5
#define DHTTYPE DHT11

//#include "Adafruit_10DOF_IMU/Adafruit_10DOF_IMU.h"

SYSTEM_THREAD(ENABLED);

int devicesHandler(String data); // forward declaration
void sendData(void);

const unsigned long REQUEST_WAIT_MS = 10000;
const unsigned long RETRY_WAIT_MS = 30000;
const unsigned long SEND_WAIT_MS = 40;

// Sensors

/* Assign a unique ID to the sensors */
//Adafruit_10DOF dof;
//Adafruit_LSM303_Accel_Unified accel(30301);
//Adafruit_LSM303_Mag_Unified mag(30302);
//Adafruit_BMP085_Unified bmp(18001);
//float seaLevelPressure = SENSORS_PRESSURE_SEALEVELHPA;
float Humidity_Si = 0;
float Temperature_Si = 0;
float Humidity_DHT = 0;
float Temperature_DHT = 0;
char resultstr[64]; //String to store the sensor temp
char humiditystr[64]; //String to store the sensor humidity
int Temperature =0;
int Humidity =0;
int power = A3;
int GND = A2;

//Create Instance of HTU21D or SI7021 temp and humidity sensor and MPL3115A2 barrometric sensor
DHT dht(DHTPIN, DHTTYPE);
Weather sensor;

enum State { STATE_REQUEST, STATE_REQUEST_WAIT, STATE_CONNECT, STATE_SEND_DATA, STATE_RETRY_WAIT };
State state = STATE_REQUEST;
unsigned long stateTime = 0;
IPAddress serverAddr;
int serverPort;
char nonce[34];
TCPClient client;
bool sensorsInitialized;

void setup() {
	Serial.begin(9600);
	Particle.function("devices", devicesHandler);

	// Initialize sensors
	//sensorsInitialized = (accel.begin() && mag.begin() && bmp.begin());
  dht.begin();
  sensor.begin();
  pinMode(power, OUTPUT);
  pinMode(GND, OUTPUT);
  digitalWrite(power, HIGH);
  digitalWrite(GND, LOW);
}

void loop() {

	switch(state) {
	case STATE_REQUEST:
		if (Particle.connected()) {
			Serial.println("sending devicesRequest");
			Particle.publish("devicesRequest", WiFi.localIP().toString().c_str(), 10, PRIVATE);
			state = STATE_REQUEST_WAIT;
			stateTime = millis();
		}
		break;

	case STATE_REQUEST_WAIT:
		if (millis() - stateTime >= REQUEST_WAIT_MS) {
			state = STATE_RETRY_WAIT;
			stateTime = millis();
		}
		break;

	case STATE_CONNECT:
		if (client.connect(serverAddr, serverPort)) {
			client.println("POST /devices HTTP/1.0");
			client.printlnf("Authorization: %s", nonce);
			client.printlnf("Content-Length: 99999999");
		    client.println();
		    state = STATE_SEND_DATA;
		}
		else {
			state = STATE_RETRY_WAIT;
			stateTime = millis();
		}
		break;

	case STATE_SEND_DATA:
		// In this state, we send data until we lose the connection to the server for whatever
		// reason. We'll to the server again.
		if (!client.connected()) {
			Serial.println("server disconnected");
			client.stop();
			state = STATE_RETRY_WAIT;
			stateTime = millis();
			break;
		}

		if (millis() - stateTime >= SEND_WAIT_MS) {
			stateTime = millis();

			sendData();
		}
		break;

	case STATE_RETRY_WAIT:
		if (millis() - stateTime >= RETRY_WAIT_MS) {
			state = STATE_REQUEST;
		}
		break;
	}
      getWeather();
      getWeather01();
      //delay(10000);
      getWeather();
      //printInfo();
      getWeather01();
      //printInfo01();
      //delay(10000);

      if (Temperature_Si>10 and Humidity_Si>10 and Temperature_Si<100 and Humidity_Si<100)
      {
        getWeather();
        //printInfo();
        //delay(20000);
        getWeather();
        //printInfo();
        //delay(20000);
        getWeather();
        //printInfo();
        //delay(20000);
        sendData();
      }
      else
        {
          getWeather01();
          //printInfo01();
          //delay(20000);
          getWeather01();
        //  printInfo01();
          //delay(20000);
          getWeather01();
          //printInfo01();
          //delay(20000);
          sendData();
        }

}
void getWeather()
{
  // Measure Relative Humidity from the HTU21D or Si7021
  Humidity_Si = sensor.getRH();
  Temperature_Si = sensor.getTempF();

  Humidity = sensor.getRH();
  Temperature = sensor.getTempF();
  char tempInChar[32];
  sprintf(tempInChar,"%0d.%d", (int)Temperature);
  sprintf(resultstr, "{\"t\":%s}", tempInChar);
  char humiInChar[32];
  sprintf(humiInChar,"%0d.%d", (int)Humidity);
  sprintf(humiditystr, "{\"t\":%s}", humiInChar);
  // Measure Temperature from the HTU21D or Si7021

  // Temperature is measured every time RH is requested.
  // It is faster, therefore, to read it from previous RH
  // measurement with getTemp() instead with readTemp()
}

void getWeather01()
{
  // Measure Relative Humidity from the HTU21D or Si7021
  Humidity_DHT = (dht.getHumidity())*1.8;
  // Measure Temperature from the HTU21D or Si7021
  Temperature_DHT = (((dht.getTempCelcius())*1.8)+32);

  Humidity = (dht.getHumidity())*1.8;
  Temperature = (((dht.getTempCelcius())*1.8)+32);
  char tempInChar[32];
  sprintf(tempInChar,"%0d.%d", (int)Temperature);
  sprintf(resultstr, "{\"t\":%s}", tempInChar);
  char humiInChar[32];
  sprintf(humiInChar,"%0d.%d", (int)Humidity);
  sprintf(humiditystr, "{\"t\":%s}", humiInChar);

  // Temperature is measured every time RH is requested.
  // It is faster, therefore, to read it from previous RH
  // measurement with getTemp() instead with readTemp()
}

void sendData(void) {
	// Called periodically when connected via TCP to the server to update data.
	// Unlike Particle.publish you can push a very large amount of data through this connection,
	// theoretically up to about 800 Kbytes/sec, but really you should probably shoot for something
	// lower than that, especially with the way connection is being served in the node.js server.


	// Taken from the Adafruit 10-DOF example code
	//sensors_event_t accel_event;
	//sensors_event_t mag_event;
	//sensors_event_t bmp_event;
	//sensors_vec_t   orientation;

	// Read the accelerometer and magnetometer
	//accel.getEvent(&accel_event);
	//mag.getEvent(&mag_event);

	// Use the new fusionGetOrientation function to merge accel/mag data
	//if (!dof.fusionGetOrientation(&accel_event, &mag_event, &orientation)) {
		// Failed to get data
		//return;
	//}
	// float orientation.roll
	// float orientation.pitch
	// float orientation.heading

	// Calculate the altitude using the barometric pressure sensor
	//bmp.getEvent(&bmp_event);
	//if (!bmp_event.pressure) {
		// Failed to get pressure
		//return;
	//}
	// Get ambient temperature in C
	//float temperature;
	//bmp.getTemperature(&temperature);

	//float altitude = bmp.pressureToAltitude(seaLevelPressure, bmp_event.pressure, temperature);

	// Use printf and manually added a \n here. The server code splits on LF only, and using println/
	// printlnf adds both a CR and LF. It's easier to parse with LF only, and it saves a byte when
	// transmitting.
	client.printf("%.3f,%.3f,%.3f,%.3f,%.2f,%.1f\n",
        Temperature,Humidity);
			//orientation.roll, orientation.pitch, orientation.heading,
			//altitude, bmp_event.pressure, temperature);

	// roll,pitch,heading,altitude,pressure,temperature
	// Example:
	// 0.000,-0.449,-49.091,263.317,982.02,27.5
	// -0.224,-0.224,-48.955,262.719,982.09,27.5
	// 0.000,-0.449,-48.704,262.719,982.09,27.5
	// 0.000,-0.449,-48.704,262.890,982.07,27.5
}

int devicesHandler(String data) {
	Serial.printlnf("devicesHandler data=%s", data.c_str());
	int addr[4];

	if (sscanf(data, "%u.%u.%u.%u,%u,%32s", &addr[0], &addr[1], &addr[2], &addr[3], &serverPort, nonce) == 6) {
		serverAddr = IPAddress(addr[0], addr[1], addr[2], addr[3]);
		Serial.printlnf("serverAddr=%s serverPort=%u nonce=%s", serverAddr.toString().c_str(), serverPort, nonce);
		state = STATE_CONNECT;
	}
	return 0;
}

#35

You should not call sendData() directly from your own code.
Rick’s FSM needs to perform the required tasks to set up the connectiin first by going through all the required individual states.
So your code should only “signal” STATE_SEND_DATA once your data has been collected and wait for state == STATE_REQUEST again before you collect the next set of data.

But to be sure, go back to Rick’s original code and try to follow through the flow and in your mind keep track of state on the individual iterations if the FSM in loop().


#36

Hi, I have removed sendData() from my code but still am not receiving any data.
What am i missing, please help .


#37

What about this?


#38

Hi, do you mean this?? sorry, I am a very beginner.


#39

Not really. Hence I also said this

You should look at the devicesHandler() function.
There you will find how STATE_CONNECT is triggered. The same would go for STATE_SEND_DATA

And I don’t quite get the use of all the getWeather()/getWeather01() calls.
Just do each of them once like this

  static uint32_t msLastWeatherReport = 0;
  if (state == STATE_REQUEST && millis() - msLastWeatherReport > 10000) {
    msLastWeatherReport = millis();
    getWeather();
    getWeather01();
    state = STATE_SEND_DATA;
  }

#40


Hi, i did this and still not receiving any data on local webpage.

Thank you.


#41

I put your code into mine but it still isnt receiving data on local webpage.
So, I tried to publish the data onto particle dashboard and it can receive data.

Sorry if my questions are too silly, I really am at lost…


#43

Hi I tested using simple photoresistor for livegraph and even then I am not receiving any data on local webpage.
Please advise me what i am doing wrong.
Thank you.

#include "Particle.h"

SYSTEM_THREAD(ENABLED);
int photoresistor = A0;
int power = A5;
int analogvalue;
int devicesHandler(String data); // forward declaration
void sendData(void);

const unsigned long REQUEST_WAIT_MS = 10000;
const unsigned long RETRY_WAIT_MS = 30000;
const unsigned long SEND_WAIT_MS = 20;


enum State { STATE_REQUEST, STATE_REQUEST_WAIT, STATE_CONNECT, STATE_SEND_DATA, STATE_RETRY_WAIT };
State state = STATE_REQUEST;
unsigned long stateTime = 0;
IPAddress serverAddr;
int serverPort;
char nonce[34];
TCPClient client;

void setup() {
	Serial.begin(9600);
	pinMode(photoresistor,INPUT);
	pinMode(power,OUTPUT);
	digitalWrite(power,HIGH);
	Particle.function("devices", devicesHandler);
}

void loop() {

	switch(state) {
	case STATE_REQUEST:
		if (Particle.connected()) {
			Serial.println("sending devicesRequest");
			Particle.publish("devicesRequest", WiFi.localIP().toString().c_str(), 10, PRIVATE);
			state = STATE_REQUEST_WAIT;
			stateTime = millis();
		}
		break;

	case STATE_REQUEST_WAIT:
		if (millis() - stateTime >= REQUEST_WAIT_MS) {
			state = STATE_RETRY_WAIT;
			stateTime = millis();
		}
		break;

	case STATE_CONNECT:
		if (client.connect(serverAddr, serverPort)) {
			client.println("POST /devices HTTP/1.0");
			client.printlnf("Authorization: %s", nonce);
			client.printlnf("Content-Length: 99999999");
		    client.println();
		    state = STATE_SEND_DATA;
		}
		else {
			state = STATE_RETRY_WAIT;
			stateTime = millis();
		}
		break;

	case STATE_SEND_DATA:
		// In this state, we send data until we lose the connection to the server for whatever
		// reason. We'll to the server again.
		if (!client.connected()) {
			Serial.println("server disconnected");
			client.stop();
			state = STATE_RETRY_WAIT;
			stateTime = millis();
			break;
		}

		if (millis() - stateTime >= SEND_WAIT_MS) {
			stateTime = millis();

			sendData();
		}
		break;

	case STATE_RETRY_WAIT:
		if (millis() - stateTime >= RETRY_WAIT_MS) {
			state = STATE_REQUEST;
		}
		break;
	}
    analogvalue = analogRead(photoresistor);
}

void sendData(void) {
	// Called periodically when connected via TCP to the server to update data.
	// Unlike Particle.publish you can push a very large amount of data through this connection,
	// theoretically up to about 800 Kbytes/sec, but really you should probably shoot for something
	// lower than that, especially with the way connection is being served in the node.js server.

	// In this simple example, we just send the value of A0. It's connected to the center terminal
	// of a potentiometer whose outer terminals are connected to GND and 3V3.
	
	int value = analogvalue;

	// Use printf and manually added a \n here. The server code splits on LF only, and using println/
	// printlnf adds both a CR and LF. It's easier to parse with LF only, and it saves a byte when
	// transmitting.
	client.printf("%d\n", value);
}

// This is the handler for the Particle.function "devices"
// The server makes this function call after this device publishes a devicesRequest event.
// The server responds with an IP address and port of the server, and a nonce (number used once) for authentication.
int devicesHandler(String data) {
	Serial.printlnf("devicesHandler data=%s", data.c_str());
	int addr[4];

	if (sscanf(data, "%u.%u.%u.%u,%u,%32s", &addr[0], &addr[1], &addr[2], &addr[3], &serverPort, nonce) == 6) {
		serverAddr = IPAddress(addr[0], addr[1], addr[2], addr[3]);
		Serial.printlnf("serverAddr=%s serverPort=%u nonce=%s", serverAddr.toString().c_str(), serverPort, nonce);
		state = STATE_CONNECT;
	}
	return 0;
}