Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /***********************************************************************************************************
- Variables used for turning a pin high/low, depending on temperature
- ***********************************************************************************************************/
- #define relayPin 7 // Set what pin the relay is connected to
- #define relayInvert 0 // Set to 1 to invert the function of the relay
- float targetTemp = 23.0; // Target temperature
- float targetHyst = 0.1; // Hysteresis determinig how much over and under target temp it should trigger
- /***********************************************************************************************************
- Variables used for reading the TMP36 temperature sensor
- ***********************************************************************************************************/
- #define TMP36pin A0
- #define readTMP36trot 500 // Time in milliseconds between temperature readings
- char tempStr[16]; // Holding the result in the json api reply
- /***********************************************************************************************************
- Variables used for averaging temperature readings
- The temperature can be accessed by opening https://api.spark.io/v1/devices/{device id}/temperature?access_token={access token}
- ***********************************************************************************************************/
- #define tempArraySize 20 // Size of the arry holding values for averaging
- double temps[tempArraySize]; // Arry holding temperature readings
- double temperature = 0; // Current average temperature
- int idx = 0; // Index of where we are in the array
- /***********************************************************************************************************
- Only used temporarily until Spark.publish(); can run from inside a function called by Spark.function();
- ***********************************************************************************************************/
- char sendPublishMessage[128];
- bool sendPublishActive = false;
- void sendPublish()
- {
- if (sendPublishActive)
- {
- sendPublishActive = false;
- Spark.publish("debug", sendPublishMessage);
- }
- }
- void setup()
- {
- pinMode(relayPin, OUTPUT); // Set pin for the relay to output
- Spark.variable("temperature", &tempStr, STRING); // Register variable so it can be accessed with the api later
- Spark.function("SETPINS", handlePinCommand);
- }
- void loop()
- {
- nodeSync(); // When last sync was and sync if needed
- cyclePins(); // Run through the tables and check if we got any pulses remaining on any pin
- readTMP36(); // Read from the temperature sensor and set the temperature variable
- sprintf(tempStr, "%4.3f", temperature); // Set the result we are going to reply with when asked by the api (returning temperature with two decimals)
- handleRelay(); // Check temperature and determine if relay should be pulled or released
- sendPublish(); // Check if we got any messages pending to be published
- }
- /***********************************************************************************************************
- Determine if the pin should be HIGH or LOW depending on temperature and hysteresis
- ***********************************************************************************************************/
- bool relayState = false;
- void handleRelay()
- {
- char sendPublishMessage[128];
- if (temperature < (targetTemp-targetHyst)) // If the temperature is below our target temperature-hysteresis then...
- {
- digitalWrite(relayPin, relayInvert?LOW:HIGH); // Set pin high, or low if function is inverted
- if (!relayState)
- {
- relayState = true;
- Spark.publish("relay", "1");
- }
- }
- else if (temperature > targetTemp+targetHyst) // If the temperature is ablove target temperature+hysteresis then..
- {
- digitalWrite(relayPin, relayInvert?HIGH:LOW); // Set pin to low, or high if function is inverted
- if (relayState)
- {
- relayState = false;
- Spark.publish("relay", "0");
- }
- }
- }
- /***********************************************************************************************************
- Read from the TMP36 sensor, calculate themperature and average tmperature
- ***********************************************************************************************************/
- unsigned long readTMP36last = 0; // Holding time of when temperature was last checked
- void readTMP36() // Function for reading from the sensor
- {
- unsigned int now = millis(); // Set the current time (from when the controller was powered on)
- if (now - readTMP36last < readTMP36trot) return; // If less than 500ms (default) has passed, just stop here and return to loop()
- readTMP36last = now; // More than 500ms (default) has passed, store the time we are reading at so we know when to do it again
- temps[idx] = ((((analogRead(TMP36pin)*3.3)/4095.0)-0.5)*100.0); // Check analog input and calculate the temperature
- if (++idx >= tempArraySize) idx = 0; // Add one to the array index, and check that we dont go above its size, if we do, set index to 0
- double total = 0; // Used to hold total value of the array
- for(int i=0; i < tempArraySize; i++) // Run through the array holding the temperatures
- {
- total += temps[i]; // Add each temperature in the array to the total
- }
- temperature = total / tempArraySize; // Set temperature variable to total temperature, divided by the array size, so we get an average temperature
- }
- /***********************************************************************************************************
- Hold info about how many pulses/steps each pin should do, the delay between them,
- when it last pulsed, and how long a pulse should be
- ***********************************************************************************************************/
- int stepsLeft[8]; // Array to store how many times it should flash the pin
- int stepDelay[8]; // Array to store how long a delay there should be between the pin state changing
- unsigned long lastStep[8]; // Array to store when the pin was changed last
- int pulseLength[8] = {50, 50, 50, 50, 50, 50, 50, 200}; // Array holding pulse length for each pin, so each pin can have a different pulse length
- void cyclePins()
- {
- for (int i = 0; i <= 8; i++) // Run through the arrays to see if any pin should be changed
- {
- unsigned long now = millis();
- if (stepsLeft[i] > 0) // Do we have to do any steps on this pin?
- {
- if (now - lastStep[i] >= stepDelay[i]) // Calculate if we are at, or passed the set delay time between pulses
- {
- lastStep[i] = now; // Set when we set the pin HIGH, so we can calculate when to set it LOW again
- digitalWrite(i, HIGH); // Set pin to HIGH
- stepsLeft[i]--; // Remove one step
- }
- }
- if (now - lastStep[i] >= pulseLength[i] && stepsLeft[i] >= 0) // Check if pin has been HIGH long enough and if we are above -1 steps left
- {
- if (stepsLeft[i] == 0) stepsLeft[i] = -1; // Set steps left to -1 so we don't get in here again
- digitalWrite(i, LOW); // Set pin to LOW
- }
- }
- }
- /***********************************************************************************************************
- Receiving the command for the pins and filling the arrays in the above section accordingly
- ***********************************************************************************************************/
- int handlePinCommand(String command)
- {
- int pinNum = 0, pinState = 0, pinDelay = 0;
- char * params = new char[command.length() + 1];
- strcpy(params, command.c_str());
- char * p = strtok(params, "-");
- int commandStep = 0;
- while (p != NULL)
- {
- //get the values for
- if (commandStep == 0)
- {
- pinNum = atoi(p);
- }
- else if (commandStep == 1)
- {
- pinState = atoi(p);
- }
- else if (commandStep == 2)
- {
- pinDelay = atoi(p);
- if (pinDelay < pulseLength[pinNum]) pinDelay = pulseLength[pinNum] + 5; // Delay between each pulse can't be less than the pulse length
- }
- commandStep++;
- p = strtok(NULL, "-");
- }
- pinMode(pinNum, OUTPUT); //Set pin to OUTPUT
- if (stepsLeft[pinNum]) // We gott a new command while doing a number of pulses
- {
- stepsLeft[pinNum] = 0;
- stepDelay[pinNum] = 0;
- lastStep[pinNum] = 0;
- digitalWrite(pinNum, LOW);
- }
- if (pinDelay > 0)
- {
- stepsLeft[pinNum] = pinState; //Store how many times the pin should flash, it is changing state for each pass, so it should be done twice for 1 on/off cycle
- stepDelay[pinNum] = pinDelay; //Store the delay between pin changes
- lastStep[pinNum] = 0; //Set the last time it changed to 0 so it will happen on next loop
- sprintf(sendPublishMessage,"Pin: %d - Flashes: %d - Delay: %d",pinNum,pinState,pinDelay);
- }
- else
- {
- stepsLeft[pinNum] = -1; // Set steps left to -1 so cyclePins() will leave it alone
- digitalWrite(pinNum, pinState?HIGH:LOW); // Set the pin defined earlier
- sprintf(sendPublishMessage,"Pin: %d - State: %d", pinNum, pinState);
- }
- sendPublishActive = true;
- return 1;
- }
- /***********************************************************************************************************
- Doing synchronization with the database to make sure controller and database is set the same
- ***********************************************************************************************************/
- TCPClient client;
- unsigned long syncStart = 0;
- unsigned long lastSync = 0;
- unsigned long nextSyncIn = 3600000; // Store how many milliseconds until we sync again
- int syncState = 1; // 1 = Need to sync now / 2 = Connected to server / 3 = Client is available / 4 = Reading from web server
- const char server[] = "www.server.com";
- bool webRead = false;
- bool isTime = true;
- String webString = String(15);
- void nodeSync()
- {
- if (syncState == 0) // Check if it is time to sync
- {
- if (millis() - lastSync >= nextSyncIn) syncState = 1; //Only check once every hour, unless we havent checked yet, or if time since overflow of millis is less than last time we checked
- }
- else if (syncState == 1) // Need to sync now
- {
- lastSync = millis(); // We read all to the end of the command line, forget the time we reached that point
- webString = "";
- char buf[256];
- if (client.connect (server, 80))
- {
- RGB.color(255, 0, 0);
- sprintf (buf, "GET /sync.php?spark=%s HTTP/1.1\r\n", Spark.deviceID().c_str());
- client.print (buf);
- sprintf (buf, "Connection: close\r\nHost: %s\r\n\r\n", server);
- client.print (buf);
- client.flush();
- syncState = 2;
- }
- }
- else if (syncState == 2) // Connected to the web server, waiting for it to reply
- {
- syncStart = millis();
- RGB.control(true);
- if (client.available())
- {
- syncState = 3;
- RGB.color(0, 255, 0);
- }
- }
- else if (syncState == 3) // Web server replied, read what was replied
- {
- RGB.color(255, 165, 0);
- if(client.available())
- {
- char c = client.read();
- if (webRead && (c == ',' || c == '>')) // , = command seperator > = no more commands
- {
- if (isTime)
- {
- isTime = false;
- char * inString = new char[webString.length() + 1];
- strcpy(inString, webString.c_str());
- nextSyncIn = atoi(inString);
- nextSyncIn *= 1000;
- }
- else
- {
- handlePinCommand(webString); //Send the string with commands to the function to execute it
- }
- webString = ""; //Empty string so it is ready for a new command
- }
- else
- {
- if (webRead) // webRead is set to true when we encounter the start of commands character
- {
- webString.concat(c);
- }
- }
- if (c == '>') // > = end of commands
- {
- webString = "";
- syncState = 4;
- }
- if (c == '<') // < = start of commands
- {
- webRead = true;
- }
- sendPublish();
- if (millis() - syncStart > 5000) // If synchronization takes more than 5 seconds, abort and try again in 60 seconds
- {
- nextSyncIn = 60000;
- RGB.control(false);
- syncState = 4;
- }
- }
- else
- {
- syncState = 4;
- }
- }
- else if (syncState == 4) // Done with the web server, stop client and set state to check the time again
- {
- client.stop();
- sendPublish();
- RGB.control(false);
- syncState = 0;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement