"I Made Something" button - Particle to Particle to Thingspeak communication

From STEAMwiki
Jump to: navigation, search


I Made something button source code:

// This #include statement was automatically added by the Particle IDE.
#include <ThingSpeak.h>
TCPClient client;


const int buttonPin = 2;
const int LEDPin = 3;
unsigned long lastDebounceTime = 0;  // the last time the output pin was toggled
unsigned long debounceDelay = 50;    // the debounce time; increase if the output flickers
unsigned long lastPublishTime = 0; //Last time made a thing was published
unsigned long publishTime = 15000; // Min time between publishing made a thing
// ThingSpeak will only accept updates every 15 seconds.




int buttonState;

unsigned long myChannelNumber = 351095;
const char * myWriteAPIKey = "Your Write Key Here";


void setup() {
  ThingSpeak.begin(client);

  pinMode(buttonPin, INPUT_PULLDOWN);
  pinMode(LEDPin, OUTPUT);

  
}

void loop() {

  
  

  if ((millis() - lastDebounceTime) > debounceDelay) {
    int reading = digitalRead(buttonPin);
    
    if (reading != buttonState) {
        buttonState = reading;
        lastDebounceTime = millis();
        // Activate!
        if (buttonState == HIGH) {
            // Activate!
            digitalWrite(LEDPin, HIGH);
            if((millis() - lastPublishTime) > publishTime){
                Particle.publish("steamlabs/madeThing/button", "1", 2160, PUBLIC);
                // ThingSpeak.writeField(myChannelNumber, 1, voltage, myWriteAPIKey);
                // ThingSpeak.writeField(myChannelNumber, fieldNumber, data, myWriteAPIKey);
                ThingSpeak.writeField(myChannelNumber, 1, 1, myWriteAPIKey);
                
                // Grab the total number of button presses. Use the ID, since it is a consecutive integer
                /* 
                https://api.thingspeak.com/channels/351095/fields/1/last.json
                */
                // From the thingspeak source:
                // readRaw(channelNumber, String(String("/fields/") + String(field) + String("/last")), readAPIKey);
                
                String resultString = ThingSpeak.readRaw(myChannelNumber, String("/fields/1/last.json"), myWriteAPIKey);
                // 
                
                //Particle.publish("debugMsg", resultString); 
                // returns:
                // 3f
                // {"created_at":"2017-10-24T01:06:43Z","entry_id":8,"field1":"1"}
                // 0
                
                // resultString = '{"created_at":"2017-10-24T01:06:43Z","entry_id":8,"field1":"1"}';
                int idPosition = find_text("entry_id", resultString);
                //Particle.publish("debugMsg", String(idPosition));
                
                
                if (idPosition > -1) {
                    int commaPosition = resultString.indexOf(',', idPosition);
                    String recordCountString = resultString.substring(idPosition+10, commaPosition);
                    int recordCount = recordCountString.toInt();
                    //Particle.publish("debugMsg", recordCountString);
                } else {
                    //Particle.publish("debugMsg", String(idPosition));
                }

                lastPublishTime = millis();
            }
            // Reset the publish time every time the button is pressed, so that spamming results in no extra published events
            // lastPublishTime = millis();
            
        } else {
            digitalWrite(LEDPin, LOW);
        }

    }
  }


}


int find_text(String needle, String haystack) {
  int foundpos = -1;
  for (int i = 0; i <= haystack.length() - needle.length(); i++) {
    if (haystack.substring(i,needle.length()+i) == needle) {
      foundpos = i;
    }
  }
  return foundpos;
}


Receiving Lamp source code:

// This #include statement was automatically added by the Particle IDE.
#include <SparkFunMicroOLED.h>
MicroOLED oled;

/*
Hardware Connections:
	This sketch was written specifically for the Photon Micro OLED Shield,
	which does all the wiring for you. If you have a Micro OLED breakout,
	use the following hardware setup:

    MicroOLED ------------- Photon
      GND ------------------- GND
      VDD ------------------- 3.3V (VCC)
    D1/MOSI ----------------- A5 (don't change)
    D0/SCK ------------------ A3 (don't change)
      D2
      D/C ------------------- D6 (can be any digital pin)
      RST ------------------- D7 (can be any digital pin)
      CS  ------------------- A2 (can be any digital pin)
*/

// This #include statement was automatically added by the Particle IDE.
#include <ThingSpeak.h>

// This #include statement was automatically added by the Particle IDE.
#include <neopixel.h>

TCPClient client;
unsigned long myChannelNumber = 351095;
const char * myWriteAPIKey = "Your API Write Key Here";



#define PIXEL_PIN D2
#define PIXEL_COUNT 16
#define PIXEL_TYPE WS2812B
Adafruit_NeoPixel strip = Adafruit_NeoPixel(PIXEL_COUNT, PIXEL_PIN, PIXEL_TYPE);

unsigned long numberOfMakes;

void setup() {
    ThingSpeak.begin(client);
    
    strip.begin();
    strip.show(); 
    
    Particle.subscribe("steamlabs/madeThing/button", madeThing, "1e003c000247353137323334");
 
    oled.begin();    // Initialize the OLED
    oled.clear(ALL); // Clear the display's internal memory
    oled.display();  // Display what's in the buffer (splashscreen)
    delay(1000);     // Delay 1000 ms
    
    checkTotalMakes();
}

void loop() {
    
    animate();
    delay(10);
    
}

int animationPattern = 4;
int defaultAnimationPattern = 4; // Normally return to this pattern
int overrideDefaultAnimPattern = 0; // Return to this pattern if it is set to something other than 0
int dimmerOverride = 0;
int animPosition = 0;
uint32_t animColour;
uint32_t animColourTarget;
uint32_t animColourOrigin;

void defaultAnimation() {
    if (overrideDefaultAnimPattern != 0) {
        changeAnimation(overrideDefaultAnimPattern);
    } else {
        changeAnimation(defaultAnimationPattern);
    }
}

void changeAnimation(int newPattern) {
    int myBrightness = dimmerOverride;
    animationPattern = newPattern;
    animPosition = 0;
    
    if(animationPattern == 1) {
        if (myBrightness == 0) myBrightness = 100;
        animPosition = 40;
    } else if(animationPattern == 2) {
         // Just on with a colour, don't change anything
        
    } else if(animationPattern == 3) {
        myBrightness = 255;
        animPosition = 0;
   } else if(animationPattern == 4) {
       // slow pulse between random colours
        animPosition = 0;
        animColourOrigin = animColour;
        animColourTarget = strip.Color( random(0, 255),  random(0, 255),  random(0, 255));
    }
    
    if (myBrightness == 0) myBrightness = 100;
    strip.setBrightness(myBrightness);
}

unsigned long myRed;
unsigned long myGreen;
unsigned long myBlue;

void animate() {
    if (animationPattern == 0) defaultAnimation();
    
    if(animationPattern == 1) {
        // Soft white pulse
        if (animPosition >= (510-40)) animPosition = 40;
        if (animPosition > 255) {
            animColour = strip.Color((510 - animPosition), (510 - animPosition), (510 - animPosition));
        } else {
            animColour = strip.Color(animPosition, animPosition, animPosition);
        }
        animPosition++;
    } else if (animationPattern == 2) {
        // Just on with a colour, don't change
        
    } else if (animationPattern == 3) {
        // Fireworks
        
        animPosition++;
        
        if (animPosition % 8 == 0) {
            animColour = strip.Color( random(0, 255),  random(0, 255),  random(0, 255));
        }
        if (animPosition > 200) {
            checkTotalMakes();
            defaultAnimation();
        }
    } else if (animationPattern == 4) {
        // Slow colour shift
        
        animPosition++;
        
        if (animPosition % 1000 == 1) {
            animPosition = 1;
            animColourOrigin = animColourTarget;
            
            // animColourTarget = strip.Color( 0,  random(0, 255),  random(0, 255));
            
            int randomPattern = random(1,6);
            
            if (randomPattern == 1) {
               
                animColourTarget = strip.Color( 100, 255, random(0, 50));
            } else  if (randomPattern == 2) {
               
                animColourTarget = strip.Color(100, 255, random(0, 100));
            } else  if (randomPattern == 3) {
               
                animColourTarget = strip.Color(100, 255, random(0, 150));
            } else  if (randomPattern == 4) {
               
                animColourTarget = strip.Color(100, 255, random(0, 200));
            } else  if (randomPattern == 5) {
               
                animColourTarget = strip.Color(100, 255, random(0, 250));
            } else  if (randomPattern == 6) {
               
                animColourTarget = strip.Color(100, 255, random(0, 100));
            } 
            
            
            // Particle.publish("DebugSTR", animColourOrigin);
        }
        
        myRed = ((Red(animColourOrigin) * (1000 - animPosition)) + (Red(animColourTarget) * animPosition)) / 1000;
        myGreen = ((Green(animColourOrigin) * (1000 - animPosition)) + (Green(animColourTarget) * animPosition)) / 1000;
        myBlue = ((Blue(animColourOrigin) * (1000 - animPosition)) + (Blue(animColourTarget) * animPosition)) / 1000;
        animColour = strip.Color( myRed, myGreen, myBlue);
        
    }
    
    for(int i=0; i < PIXEL_COUNT; i++) {
        strip.setPixelColor(i, animColour);
    }
    strip.show();
    
}

void madeThing(const char *event, const char *data) {
    
    changeAnimation(3);
    checkTotalMakes();
    
}

void checkTotalMakes() {
    String resultString = ThingSpeak.readRaw(myChannelNumber, String("/fields/1/last.json"), myWriteAPIKey);
    // 
    
    //Particle.publish("debugMsg", resultString); 
    // returns:
    // 3f
    // {"created_at":"2017-10-24T01:06:43Z","entry_id":8,"field1":"1"}
    // 0
    
    // resultString = '{"created_at":"2017-10-24T01:06:43Z","entry_id":8,"field1":"1"}';
    int idPosition = find_text("entry_id", resultString);
    //Particle.publish("debugMsg", String(idPosition));
    
    
    if (idPosition > -1) {
        int commaPosition = resultString.indexOf(',', idPosition);
        String recordCountString = resultString.substring(idPosition+10, commaPosition);
        int recordCount = recordCountString.toInt();
        
        numberOfMakes = recordCount;
        
        //Particle.publish("debugMsg", recordCountString);
    } else {
        //Particle.publish("debugMsg", String(idPosition));
    }
    
    int middleX = oled.getLCDWidth() / 2;
    int middleY = oled.getLCDHeight() / 2;
    String tempStr;
    
    oled.clear(PAGE);     // Clear the display
   
    tempStr = "steamlabs";
    oled.setCursor(10, 0);
    oled.setFontType(0);  
    oled.print(tempStr);
    
    //oled.setCursor(0, 15); // Set cursor to middle-left
    tempStr = (String)numberOfMakes;
    oled.setCursor(middleX - (oled.getFontWidth() * (tempStr.length()/2)), 15);
    oled.setFontType(1);  // Use the biggest font
    oled.print(tempStr);
    
    tempStr = "makes!";
    oled.setCursor(20, 35);
    oled.setFontType(0);  
    oled.print(tempStr);
    
    oled.display();       // Draw on the screen
    delay(10);
    
}

int find_text(String needle, String haystack) {
  int foundpos = -1;
  for (int i = 0; i <= haystack.length() - needle.length(); i++) {
    if (haystack.substring(i,needle.length()+i) == needle) {
      foundpos = i;
    }
  }
  return foundpos;
}

 // Returns the Red component of a 32-bit color
uint8_t Red(uint32_t color)
{
    return (color >> 16) & 0xFF;
}

// Returns the Green component of a 32-bit color
uint8_t Green(uint32_t color)
{
    return (color >> 8) & 0xFF;
}

// Returns the Blue component of a 32-bit color
uint8_t Blue(uint32_t color)
{
    return color & 0xFF;
}