Well, it is 364 lines and it is working with threads. I think everyone will be bored, but here goes:
SYSTEM_THREAD(ENABLED);
SYSTEM_MODE(AUTOMATIC);
#include "nokia-5110-lcd.h"
#include "MQTT.h"
#define mqtt_client_id "01"
#define mqtt_user "user"
#define mqtt_pass "pass"
#define MQTT_PAYLOAD_SIZE 100
#define DIFF_PIN A0
#define LCD_RS D5
#define LCD_EN D4
//#define SERIAL_DEBUG
#ifdef SERIAL_DEBUG
#define debug_print Serial.printf
#else
#define debug_print //
#endif
int LED = D7;
int blPin = D5;
Nokia5110LCD::Display nokiaLCD(D3, D1, D6, blPin);
void callback(char* topic, byte* payload, unsigned int length);
// struct for the distance ultrasonice sensor.
typedef struct {
char vec[50];
int index;
int distance;
} dist_par;
dist_par d_pars;
uint32_t diff;
double fdiff;
bool automatic_operation = 0;
double water_level_low;
double water_level_high;
#define SERVER_IP "xx.xx.xx.xx"
MQTT mqtt_client(SERVER_IP, 1883, callback);
// Application Threads.
//Thread *read_diff_press_thread;
Thread *expose_diff_sensor_threads;
Thread *start_distance_measurement_thread;
Thread *time_thread;
Thread *serial1_thread;
os_thread_return_t serial1_task(void *param)
{
while (1) {
while (Serial1.available()) {
//if (Serial1.available()) {
d_pars.vec[d_pars.index] = Serial1.read();
d_pars.index++;
if (d_pars.index == 4) {
if (d_pars.vec[0] == 0xFF) {
if (d_pars.vec[3] = ((d_pars.vec[0] + d_pars.vec[1] + d_pars.vec[2]) & 0x00FF)) {
d_pars.distance = (d_pars.vec[1] << 8) + d_pars.vec[2];
}
else {
debug_print("crc wrong\n");
}
}
else {
debug_print("first char wrong\n");
}
}
}
//delay(20);
delay(100);
}
}
os_thread_return_t time_task(void *param)
{
char msg[20];
int current_seconds, previous_seconds;
int previous_day, current_day;
previous_day = current_day = 0;
previous_seconds = current_seconds = 0;
uint32_t no_wifi_counter = 0;
uint32_t no_particle_cloud_counter = 0;
while (1) {
no_wifi_counter = 0;
current_seconds = Time.second();
if (previous_seconds != current_seconds) {
sprintf(msg, "%02d:%02d:%02d ", Time.hour(), Time.minute(), Time.second());
current_day = Time.day();
nokiaLCD.setStr(msg, 0, 32, BLACK);
ATOMIC_BLOCK() {
nokiaLCD.updateDisplay();
}
previous_seconds = current_seconds;
if (Time.month() == 10) {
if (Time.weekday() == 1) {
if ((Time.day() <= 31) && (Time.day() >= 25)) {
Time.endDST();
}
}
}
else if (Time.month() == 3) {
if (Time.weekday() == 1) {
if ((Time.day() <= 30) && (Time.day() >= 24)) {
Time.setDSTOffset(1);
Time.beginDST();
}
}
}
}
// Watchdog!!
else if (WiFi.ready() != true) {
no_wifi_counter++;
if (no_wifi_counter == 400) {
System.reset();
}//if 20 seconds without connection
}
if (Particle.connected() == false) {
no_particle_cloud_counter++;
if (no_particle_cloud_counter == 200) {
System.reset();
}
}
else {
no_particle_cloud_counter = 0;
}
if (current_day != previous_day) {
previous_day = current_day;
if (Particle.connected()) {
Particle.syncTime();
}
}
delay(50);
}
}
void callback(char* topic, byte* payload, unsigned int length) {
char msg[MQTT_PAYLOAD_SIZE];
uint8_t i;
debug_print("MQTT message= %s, length = %d\n", topic, length);
if (length > MQTT_PAYLOAD_SIZE) {
return;
}
if (strcmp(topic, "6e06744c735ee16bb87078c6/dl/LED") == 0) {
if ((char)payload[0] == '0') {
digitalWrite(LED, LOW);
}
else if ((char)payload[0] == '1') {
digitalWrite(LED, HIGH);
}
}
else if (strcmp(topic, "6e06744c735ee16bb87078c6/dl/auto") == 0) {
if ((char)payload[0] == '1') {
automatic_operation = 1;
debug_print("automatic operation\n");
}
else if ((char)payload[0] == '0') {
automatic_operation = 0;
debug_print("manual operation\n");
}
}
else if (strcmp(topic, "6e06744c735ee16bb87078c6/dl/water_low") == 0) {
for (i = 0; i < length; i++) {
msg[i] = payload[i];
}
msg[i] = 0;
water_level_low = atof(msg);
debug_print("%f\n", water_level_low);
}
else if (strcmp(topic, "6e06744c735ee16bb87078c6/dl/water_high") == 0) {
for (i = 0; i < length; i++) {
msg[i] = payload[i];
}
msg[i] = 0;
water_level_high = atof(msg);
debug_print("%f\n", water_level_high);
}
else if (strcmp(topic, "6e06744c735ee16bb87078c6/dl/reset") == 0) {
System.reset();
}
}
os_thread_return_t start_distance_measurement_task(void *param)
{
Serial1.begin(9600, SERIAL_8N1);
serial1_thread = new Thread("serial1", serial1_task, 0);
delay(100);
while (1) {
Serial1.write(0x55);
d_pars.index = 0;
delay(500);
}
}
os_thread_return_t expose_diff_tasks(void *param)
{
char diffValStr[40];
char distanceStr[40];
char msg[20];
unsigned long s_time, e_time;
while (1) {
ATOMIC_BLOCK() {
fdiff = (((double)diff * 3.3) / 4095);
}
fdiff = ((fdiff/5) - 0.04) / 0.018;
fdiff /= 0.0980665;
sprintf(diffValStr, "P1: %.2f cm", fdiff);
sprintf(distanceStr, "d: %d cm", d_pars.distance / 10);
if (WiFi.ready()) {
/*s_time = micros();
Particle.publish("diff_distance", diffValStr, PRIVATE);
e_time = micros();
debug_print("cloud: %s, time = %d\n", distanceStr, e_time - s_time);*/
s_time = micros();
Particle.publish("ultra_distance", distanceStr, PRIVATE);
e_time = micros();
debug_print("cloud: %s, time = %d\n", diffValStr, e_time - s_time);
sprintf(msg, "%s", WiFi.SSID());
msg[14] = 0;
nokiaLCD.setStr(msg, 0, 40, BLACK);
}
nokiaLCD.setStr(" ", 0, 8, BLACK);
nokiaLCD.setStr(diffValStr , 0, 8, BLACK);
nokiaLCD.setStr(" ", 0, 0, BLACK);
nokiaLCD.setStr(distanceStr , 0, 0, BLACK);
ATOMIC_BLOCK() {
nokiaLCD.updateDisplay();
}
if (mqtt_client.isConnected()) {
/*sprintf (msg, "%.2f", fdiff);
s_time = micros();
mqtt_client.publish("6e06744c735ee16bb87078c6/ul/1", msg);
e_time = micros();
debug_print("mqtt d2:%s, time= %d us\n", msg, e_time - s_time);*/
sprintf (msg, "%.2f", (double)d_pars.distance / 10);
s_time = micros();
mqtt_client.publish("6e06744c735ee16bb87078c6/ul/0", msg);
e_time = micros();
debug_print("mqtt d1: %s, time= %d us\n", msg, e_time - s_time);
}
delay(3000);
}
}
os_thread_return_t read_diff_press_task(void *param)
{
setADCSampleTime(ADC_SampleTime_480Cycles);
while (1) {
diff = analogRead(DIFF_PIN);
delay(300);
}
}
void mqtt_reconnect(void)
{
// Loop until we're reconnected
while (!mqtt_client.isConnected()) {
debug_print("Attempting MQTT connection...\n");
// Attempt to connect
if (mqtt_client.connect(mqtt_client_id, mqtt_user, mqtt_pass)) {
debug_print("connected\n");
mqtt_client.subscribe("asdf/dl/+");
}
else {
debug_print("failed, try again in 5 seconds\n");
// Wait 5 seconds before retrying
delay(5000);
}
}
}
void setup() {
pinMode(LED, OUTPUT);
digitalWrite(LED, LOW);
nokiaLCD.begin(); // This will setup our pins, and initialize the LCD
nokiaLCD.setContrast(55); // Pretty good value, play around with it
nokiaLCD.clearDisplay(WHITE);
nokiaLCD.updateDisplay();
//read_diff_press_thread = new Thread("read_diff_press", read_diff_press_task, 0);
expose_diff_sensor_threads = new Thread("expose_diff", expose_diff_tasks, 0);
start_distance_measurement_thread = new Thread("start_distance measurement", start_distance_measurement_task, 0);
WiFi.useDynamicIP();
while (WiFi.ready() != true)
{
delay(10);
}
#ifdef SERIAL_DEBUG
Serial.begin(115200);
while(!Serial.isConnected());
#endif
debug_print("Photon is connected\n");
// mqtt
debug_print("trying to connect to ");
mqtt_client.connect(mqtt_client_id, mqtt_user, mqtt_pass);
if (mqtt_client.isConnected()) {
debug_print("connected!\n");
mqtt_client.subscribe("asdf/dl/+");
}
Time.zone(2);
Time.setDSTOffset(1);
//Check for DST.
if ((Time.month() > 3) && (Time.month() < 10)) {
Time.beginDST();
}
else if (Time.month() == 3) {
if ((Time.weekday() >= 25) && ((31 - Time.day() + 1) <= Time.weekday())) {
Time.beginDST();
}
}
else if (Time.month() == 10) {
if ((Time.weekday() <= 24) && ((30 - Time.day() + 1) >= Time.weekday())) {
Time.beginDST();
}
}
time_thread = new Thread("time_update", time_task, 0);
}
void loop() {
if (mqtt_client.isConnected()) {
mqtt_client.loop();
}
else if (WiFi.ready() == true) {
mqtt_reconnect();
}
}