Advertisement
bld

Untitled

bld
Mar 24th, 2014
28
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 13.65 KB | None | 0 0
  1. /***********************************************************************************************************
  2. Variables used for turning a pin high/low, depending on temperature
  3. ***********************************************************************************************************/
  4. #define relayPin                7       // Set what pin the relay is connected to
  5. #define relayInvert             0       // Set to 1 to invert the function of the relay
  6.  
  7. float targetTemp =              23.0;   // Target temperature
  8. float targetHyst =              0.1;    // Hysteresis determinig how much over and under target temp it should trigger
  9.  
  10.  
  11. /***********************************************************************************************************
  12. Variables used for reading the TMP36 temperature sensor
  13. ***********************************************************************************************************/
  14. #define TMP36pin                A0
  15. #define readTMP36trot 500               // Time in milliseconds between temperature readings
  16. char tempStr[16];                       // Holding the result in the json api reply
  17.  
  18. /***********************************************************************************************************
  19. Variables used for averaging temperature readings
  20. The temperature can be accessed by opening https://api.spark.io/v1/devices/{device id}/temperature?access_token={access token}
  21. ***********************************************************************************************************/
  22. #define tempArraySize           20      // Size of the arry holding values for averaging
  23. double temps[tempArraySize];            // Arry holding temperature readings
  24. double temperature =            0;      // Current average temperature
  25. int idx =                       0;      // Index of where we are in the array
  26.  
  27.  
  28. /***********************************************************************************************************
  29. Only used temporarily until Spark.publish(); can run from inside a function called by Spark.function();
  30. ***********************************************************************************************************/
  31. char sendPublishMessage[128];
  32. bool sendPublishActive = false;
  33. void sendPublish()
  34. {
  35.     if (sendPublishActive)
  36.     {
  37.         sendPublishActive = false;
  38.         Spark.publish("debug", sendPublishMessage);
  39.     }
  40. }
  41.  
  42.  
  43. void setup()
  44. {
  45.     pinMode(relayPin, OUTPUT);  // Set pin for the relay to output
  46.     Spark.variable("temperature", &tempStr, STRING);    // Register variable so it can be accessed with the api later
  47.    
  48.     Spark.function("SETPINS", handlePinCommand);
  49. }
  50.  
  51.  
  52. void loop()
  53. {
  54.     nodeSync(); // When last sync was and sync if needed
  55.    
  56.     cyclePins(); // Run through the tables and check if we got any pulses remaining on any pin
  57.    
  58.     readTMP36();    // Read from the temperature sensor and set the temperature variable
  59.     sprintf(tempStr, "%4.3f", temperature); // Set the result we are going to reply with when asked by the api (returning temperature with two decimals)
  60.    
  61.     handleRelay(); // Check temperature and determine if relay should be pulled or released
  62.    
  63.     sendPublish(); // Check if we got any messages pending to be published
  64. }
  65.  
  66. /***********************************************************************************************************
  67. Determine if the pin should be HIGH or LOW depending on temperature and hysteresis
  68. ***********************************************************************************************************/
  69. bool relayState = false;
  70. void handleRelay()
  71. {
  72.     char sendPublishMessage[128];
  73.     if (temperature < (targetTemp-targetHyst)) // If the temperature is below our target temperature-hysteresis then...
  74.     {
  75.         digitalWrite(relayPin, relayInvert?LOW:HIGH); // Set pin high, or low if function is inverted
  76.        
  77.         if (!relayState)
  78.         {
  79.             relayState = true;
  80.             Spark.publish("relay", "1");
  81.         }
  82.     }
  83.     else if (temperature > targetTemp+targetHyst) // If the temperature is ablove target temperature+hysteresis then..
  84.     {
  85.         digitalWrite(relayPin, relayInvert?HIGH:LOW); // Set pin to low, or high if function is inverted
  86.        
  87.         if (relayState)
  88.         {
  89.             relayState = false;
  90.             Spark.publish("relay", "0");
  91.         }
  92.     }
  93. }
  94.  
  95.  
  96. /***********************************************************************************************************
  97. Read from the TMP36 sensor, calculate themperature and average tmperature
  98. ***********************************************************************************************************/
  99. unsigned long readTMP36last =   0;      // Holding time of when temperature was last checked
  100. void readTMP36() // Function for reading from the sensor
  101. {
  102.     unsigned int now = millis(); // Set the current time (from when the controller was powered on)
  103.    
  104.     if (now - readTMP36last < readTMP36trot) return; // If less than 500ms (default) has passed, just stop here and return to loop()
  105.  
  106.     readTMP36last = now; // More than 500ms (default) has passed, store the time we are reading at so we know when to do it again
  107.    
  108.     temps[idx] = ((((analogRead(TMP36pin)*3.3)/4095.0)-0.5)*100.0); // Check analog input and calculate the temperature
  109.    
  110.     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
  111.    
  112.     double total = 0; // Used to hold total value of the array
  113.     for(int i=0; i < tempArraySize; i++) // Run through the array holding the temperatures
  114.     {
  115.         total += temps[i]; // Add each temperature in the array to the total
  116.     }
  117.     temperature = total / tempArraySize; // Set temperature variable to total temperature, divided by the array size, so we get an average temperature
  118. }
  119.  
  120.  
  121. /***********************************************************************************************************
  122. Hold info about how many pulses/steps each pin should do, the delay between them,
  123. when it last pulsed, and how long a pulse should be
  124. ***********************************************************************************************************/
  125. int stepsLeft[8];                                       // Array to store how many times it should flash the pin
  126. int stepDelay[8];                                       // Array to store how long a delay there should be between the pin state changing
  127. unsigned long lastStep[8];                              // Array to store when the pin was changed last
  128. 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
  129.  
  130. void cyclePins()
  131. {
  132.     for (int i = 0; i <= 8; i++) // Run through the arrays to see if any pin should be changed
  133.     {
  134.         unsigned long now = millis();
  135.        
  136.         if (stepsLeft[i] > 0) // Do we have to do any steps on this pin?
  137.         {
  138.             if (now - lastStep[i] >= stepDelay[i]) // Calculate if we are at, or passed the set delay time between pulses
  139.             {
  140.                 lastStep[i] = now; // Set when we set the pin HIGH, so we can calculate when to set it LOW again
  141.                 digitalWrite(i, HIGH); // Set pin to HIGH
  142.                 stepsLeft[i]--; // Remove one step
  143.             }
  144.         }
  145.        
  146.         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
  147.         {
  148.             if (stepsLeft[i] == 0) stepsLeft[i] = -1; // Set steps left to -1 so we don't get in here again
  149.            
  150.             digitalWrite(i, LOW); // Set pin to LOW
  151.         }
  152.     }
  153. }
  154.  
  155. /***********************************************************************************************************
  156. Receiving the command for the pins and filling the arrays in the above section accordingly
  157. ***********************************************************************************************************/
  158. int handlePinCommand(String command)
  159. {
  160.     int pinNum = 0, pinState = 0, pinDelay = 0;
  161.    
  162.     char * params = new char[command.length() + 1];
  163.     strcpy(params, command.c_str());
  164.    
  165.     char * p = strtok(params, "-");
  166.    
  167.     int commandStep = 0;
  168.     while (p != NULL)
  169.     {
  170.         //get the values for
  171.         if (commandStep == 0)
  172.         {
  173.             pinNum = atoi(p);
  174.         }
  175.         else if (commandStep == 1)
  176.         {
  177.             pinState = atoi(p);
  178.         }
  179.         else if (commandStep == 2)
  180.         {
  181.             pinDelay = atoi(p);
  182.             if (pinDelay < pulseLength[pinNum]) pinDelay = pulseLength[pinNum] + 5; // Delay between each pulse can't be less than the pulse length
  183.         }
  184.        
  185.         commandStep++;
  186.         p = strtok(NULL, "-");
  187.     }
  188.  
  189.     pinMode(pinNum, OUTPUT); //Set pin to OUTPUT
  190.    
  191.     if (stepsLeft[pinNum]) // We gott a new command while doing a number of pulses
  192.     {
  193.         stepsLeft[pinNum] = 0;
  194.         stepDelay[pinNum] = 0;
  195.         lastStep[pinNum] = 0;
  196.         digitalWrite(pinNum, LOW);
  197.     }
  198.  
  199.     if (pinDelay > 0)
  200.     {
  201.         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
  202.         stepDelay[pinNum] = pinDelay; //Store the delay between pin changes
  203.         lastStep[pinNum] = 0; //Set the last time it changed to 0 so it will happen on next loop
  204.        
  205.         sprintf(sendPublishMessage,"Pin: %d - Flashes: %d - Delay: %d",pinNum,pinState,pinDelay);
  206.     }
  207.     else
  208.     {
  209.         stepsLeft[pinNum] = -1; // Set steps left to -1 so cyclePins() will leave it alone
  210.         digitalWrite(pinNum, pinState?HIGH:LOW); // Set the pin defined earlier
  211.         sprintf(sendPublishMessage,"Pin: %d - State: %d", pinNum, pinState);
  212.     }
  213.    
  214.     sendPublishActive = true;
  215.    
  216.     return 1;
  217. }
  218.  
  219. /***********************************************************************************************************
  220. Doing synchronization with the database to make sure controller and database is set the same
  221. ***********************************************************************************************************/
  222. TCPClient client;
  223.  
  224. unsigned long syncStart = 0;
  225. unsigned long lastSync = 0;
  226. unsigned long nextSyncIn = 3600000; // Store how many milliseconds until we sync again
  227. void nodeSync()
  228. {
  229.     if ((millis() - lastSync < nextSyncIn  && lastSync != 0) && millis() >= lastSync) return; //Only check once every hour, unless we havent checked yet, or if time since overflow of millis is less than last time we checked
  230.    
  231.     syncStart = millis();
  232.    
  233.     unsigned long tic = millis();
  234.     char send2PublishMessage[128];
  235.    
  236.     RGB.control(true);
  237.    
  238.     const char server[] = "www.server.com";
  239.    
  240.     if (sendGetRequest (server))
  241.     {  
  242.         while (!client.available())
  243.         {
  244.             RGB.color(0, 255, 0);
  245.         }
  246.        
  247.         RGB.color(255, 165, 0);
  248.        
  249.         bool webRead = false;
  250.         bool isTime = true;
  251.         String webString = String(15);
  252.         webString = "";
  253.        
  254.         while (client.available())
  255.         {
  256.             char c = client.read();
  257.            
  258.             if (webRead && (c == ',' || c == '>')) // , = command seperator > = no more commands
  259.             {
  260.                 if (isTime)
  261.                 {
  262.                     isTime = false;
  263.                    
  264.                     char * inString = new char[webString.length() + 1];
  265.                     strcpy(inString, webString.c_str());
  266.                     nextSyncIn = atoi(inString);
  267.                     nextSyncIn *= 1000;
  268.                    
  269.                     sprintf(send2PublishMessage,"Next synchronization in: %i seconds", (nextSyncIn/1000));
  270.                     Spark.publish("debug", send2PublishMessage);
  271.                 }
  272.                 else
  273.                 {
  274.                     handlePinCommand(webString); //Send the string with commands to the function to execute it
  275.                 }
  276.                 webString = ""; //Empty string so it is ready for a new command
  277.             }
  278.             else
  279.             {
  280.                 if (webRead) // webRead is set to true when we encounter the start of commands character
  281.                 {
  282.                    webString.concat(c);
  283.                 }
  284.             }
  285.            
  286.             if (c == '>') // > = end of commands
  287.             {
  288.                 lastSync = millis(); // We read all to the end of the command line, forget the time we reached that point
  289.                 webString = "";
  290.                 break;
  291.             }
  292.            
  293.             if (c == '<') // < = start of commands
  294.             {
  295.                 webRead = true;
  296.             }
  297.            
  298.             sendPublish();
  299.            
  300.             if (millis() - syncStart > 5000) // If synchronization takes more than 5 seconds, abort and try again in 60 seconds
  301.             {
  302.                 nextSyncIn = 60000;
  303.                 RGB.control(false);
  304.                 break;
  305.             }
  306.         }
  307.        
  308.         client.stop();
  309.     }
  310.    
  311.     sendPublish();
  312.    
  313.     unsigned long toc = millis();
  314.     sprintf(send2PublishMessage,"Synchronization took : %ims", (toc-tic));
  315.     Spark.publish("debug", send2PublishMessage);
  316.    
  317.     RGB.control(false);
  318. }
  319.  
  320. char buf[256];
  321. int sendGetRequest (const char *server)
  322. {
  323.     if (client.connect (server, 80))
  324.     {
  325.         RGB.color(255, 0, 0);
  326.         sprintf (buf, "GET /sync.php?spark=%s HTTP/1.1\r\n", Spark.deviceID().c_str());
  327.         client.print (buf);
  328.         sprintf (buf, "Connection: close\r\nHost: %s\r\n\r\n", server);
  329.         client.print (buf);
  330.         client.flush();
  331.         return 1;
  332.     }
  333.     return 0;
  334. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement