"I Made Something" button - Particle to Particle to Thingspeak communication
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;
}