Last active
January 2, 2016 12:09
-
-
Save wgbartley/8301007 to your computer and use it in GitHub Desktop.
Combines all my environmental sensors into a single sketch. Data is retrieved by passing a string to fnrouter() exposed to the cloude API.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <math.h> | |
#define MAXTIMINGS 85 | |
#define cli noInterrupts | |
#define sei interrupts | |
#define DHT11 11 | |
#define DHT22 22 | |
#define DHT21 21 | |
#define AM2301 21 | |
class DHT { | |
private: | |
uint8_t data[6]; | |
uint8_t _pin, _type, _count; | |
bool read(void); | |
unsigned long _lastreadtime; | |
bool firstreading; | |
public: | |
DHT(uint8_t pin, uint8_t type, uint8_t count=6); | |
void begin(void); | |
float readTemperature(bool S=false); | |
float convertCtoF(float); | |
float readHumidity(void); | |
}; | |
DHT::DHT(uint8_t pin, uint8_t type, uint8_t count) { | |
_pin = pin; | |
_type = type; | |
_count = count; | |
firstreading = true; | |
} | |
void DHT::begin(void) { | |
// set up the pins! | |
pinMode(_pin, INPUT); | |
digitalWrite(_pin, HIGH); | |
_lastreadtime = 0; | |
} | |
//boolean S == Scale. True == Farenheit; False == Celcius | |
float DHT::readTemperature(bool S) { | |
float _f; | |
if (read()) { | |
switch (_type) { | |
case DHT11: | |
_f = data[2]; | |
if(S) | |
_f = convertCtoF(_f); | |
return _f; | |
case DHT22: | |
case DHT21: | |
_f = data[2] & 0x7F; | |
_f *= 256; | |
_f += data[3]; | |
_f /= 10; | |
if (data[2] & 0x80) | |
_f *= -1; | |
if(S) | |
_f = convertCtoF(_f); | |
return _f; | |
} | |
} | |
return NAN; | |
} | |
float DHT::convertCtoF(float c) { | |
return c * 9 / 5 + 32; | |
} | |
float DHT::readHumidity(void) { | |
float _f; | |
if (read()) { | |
switch (_type) { | |
case DHT11: | |
_f = data[0]; | |
return _f; | |
case DHT22: | |
case DHT21: | |
_f = data[0]; | |
_f *= 256; | |
_f += data[1]; | |
_f /= 10; | |
return _f; | |
} | |
} | |
return NAN; | |
} | |
bool DHT::read(void) { | |
uint8_t laststate = HIGH; | |
uint8_t counter = 0; | |
uint8_t j = 0, i; | |
unsigned long currenttime; | |
// pull the pin high and wait 250 milliseconds | |
digitalWrite(_pin, HIGH); | |
delay(250); | |
currenttime = millis(); | |
if (currenttime < _lastreadtime) { | |
// ie there was a rollover | |
_lastreadtime = 0; | |
} | |
if (!firstreading && ((currenttime - _lastreadtime) < 2000)) { | |
//delay(2000 - (currenttime - _lastreadtime)); | |
return true; // return last correct measurement | |
} | |
firstreading = false; | |
_lastreadtime = millis(); | |
data[0] = data[1] = data[2] = data[3] = data[4] = 0; | |
// now pull it low for ~20 milliseconds | |
pinMode(_pin, OUTPUT); | |
digitalWrite(_pin, LOW); | |
delay(20); | |
cli(); | |
digitalWrite(_pin, HIGH); | |
delayMicroseconds(40); | |
pinMode(_pin, INPUT); | |
// read in timings | |
for ( i=0; i< MAXTIMINGS; i++) { | |
counter = 0; | |
while (digitalRead(_pin) == laststate) { | |
counter++; | |
delayMicroseconds(1); | |
if (counter == 255) | |
break; | |
} | |
laststate = digitalRead(_pin); | |
if (counter == 255) | |
break; | |
// ignore first 3 transitions | |
if ((i >= 4) && (i%2 == 0)) { | |
// shove each bit into the storage bytes | |
data[j/8] <<= 1; | |
if (counter > _count) | |
data[j/8] |= 1; | |
j++; | |
} | |
} | |
sei(); | |
// check we read 40 bits and that the checksum matches | |
if ((j >= 40) && (data[4] == ((data[0] + data[1] + data[2] + data[3]) & 0xFF))) | |
return true; | |
return false; | |
} | |
// ONE-WIRE CLASS | |
#define OneWire_h | |
#include <inttypes.h> | |
#define ONEWIRE_SEARCH 1 | |
#define ONEWIRE_CRC 1 | |
#define ONEWIRE_CRC16 1 | |
#define FALSE 0 | |
#define TRUE 1 | |
class OneWire { | |
private: | |
uint16_t _pin; | |
void DIRECT_WRITE_LOW(void); | |
void DIRECT_MODE_OUTPUT(void); | |
void DIRECT_WRITE_HIGH(void); | |
void DIRECT_MODE_INPUT(void); | |
uint8_t DIRECT_READ(void); | |
unsigned char ROM_NO[8]; | |
uint8_t LastDiscrepancy; | |
uint8_t LastFamilyDiscrepancy; | |
uint8_t LastDeviceFlag; | |
public: | |
OneWire( uint16_t pin); | |
uint8_t reset(void); | |
void select(const uint8_t rom[8]); | |
void skip(void); | |
void write(uint8_t v, uint8_t power = 0); | |
void write_bytes(const uint8_t *buf, uint16_t count, bool power = 0); | |
uint8_t read(void); | |
void read_bytes(uint8_t *buf, uint16_t count); | |
void write_bit(uint8_t v); | |
uint8_t read_bit(void); | |
void depower(void); | |
void reset_search(); | |
void target_search(uint8_t family_code); | |
uint8_t search(uint8_t *newAddr); | |
static uint8_t crc8(uint8_t *addr, uint8_t len); | |
static bool check_crc16(const uint8_t* input, uint16_t len, const uint8_t* inverted_crc, uint16_t crc = 0); | |
static uint16_t crc16(const uint8_t* input, uint16_t len, uint16_t crc = 0); | |
}; | |
OneWire::OneWire(uint16_t pin) { | |
pinMode(pin, INPUT); | |
_pin = pin; | |
} | |
void OneWire::DIRECT_WRITE_LOW(void) { | |
PIN_MAP[_pin].gpio_peripheral->BRR = PIN_MAP[_pin].gpio_pin; | |
} | |
void OneWire::DIRECT_MODE_OUTPUT(void) { | |
GPIO_TypeDef *gpio_port = PIN_MAP[_pin].gpio_peripheral; | |
uint16_t gpio_pin = PIN_MAP[_pin].gpio_pin; | |
GPIO_InitTypeDef GPIO_InitStructure; | |
if (gpio_port == GPIOA ) | |
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); | |
else if (gpio_port == GPIOB ) | |
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); | |
GPIO_InitStructure.GPIO_Pin = gpio_pin; | |
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; | |
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; | |
PIN_MAP[_pin].pin_mode = OUTPUT; | |
GPIO_Init(gpio_port, &GPIO_InitStructure); | |
} | |
void OneWire::DIRECT_WRITE_HIGH(void) { | |
PIN_MAP[_pin].gpio_peripheral->BSRR = PIN_MAP[_pin].gpio_pin; | |
} | |
void OneWire::DIRECT_MODE_INPUT(void) { | |
GPIO_TypeDef *gpio_port = PIN_MAP[_pin].gpio_peripheral; | |
uint16_t gpio_pin = PIN_MAP[_pin].gpio_pin; | |
GPIO_InitTypeDef GPIO_InitStructure; | |
if (gpio_port == GPIOA ) | |
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE); | |
else if (gpio_port == GPIOB ) | |
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE); | |
GPIO_InitStructure.GPIO_Pin = gpio_pin; | |
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; | |
PIN_MAP[_pin].pin_mode = INPUT; | |
GPIO_Init(gpio_port, &GPIO_InitStructure); | |
} | |
uint8_t OneWire::DIRECT_READ(void) { | |
return GPIO_ReadInputDataBit(PIN_MAP[_pin].gpio_peripheral, PIN_MAP[_pin].gpio_pin); | |
} | |
uint8_t OneWire::reset(void) { | |
uint8_t r; | |
uint8_t retries = 125; | |
noInterrupts(); | |
DIRECT_MODE_INPUT(); | |
interrupts(); | |
do { | |
if (--retries == 0) | |
return 0; | |
delayMicroseconds(2); | |
} while ( !DIRECT_READ()); | |
noInterrupts(); | |
DIRECT_WRITE_LOW(); | |
DIRECT_MODE_OUTPUT(); // drive output low | |
interrupts(); | |
delayMicroseconds(480); | |
noInterrupts(); | |
DIRECT_MODE_INPUT(); // allow it to float | |
delayMicroseconds(70); | |
r = !DIRECT_READ(); | |
interrupts(); | |
delayMicroseconds(410); | |
return r; | |
} | |
void OneWire::write_bit(uint8_t v) { | |
if (v & 1) { | |
noInterrupts(); | |
DIRECT_WRITE_LOW(); | |
DIRECT_MODE_OUTPUT(); // drive output low | |
delayMicroseconds(10); | |
DIRECT_WRITE_HIGH(); // drive output high | |
interrupts(); | |
delayMicroseconds(55); | |
} else { | |
noInterrupts(); | |
DIRECT_WRITE_LOW(); | |
DIRECT_MODE_OUTPUT(); // drive output low | |
delayMicroseconds(65); | |
DIRECT_WRITE_HIGH(); // drive output high | |
interrupts(); | |
delayMicroseconds(5); | |
} | |
} | |
uint8_t OneWire::read_bit(void) { | |
uint8_t r; | |
noInterrupts(); | |
DIRECT_MODE_OUTPUT(); | |
DIRECT_WRITE_LOW(); | |
delayMicroseconds(3); | |
DIRECT_MODE_INPUT(); // let pin float, pull up will raise | |
delayMicroseconds(10); | |
r = DIRECT_READ(); | |
interrupts(); | |
delayMicroseconds(53); | |
return r; | |
} | |
void OneWire::write(uint8_t v, uint8_t power /* = 0 */) { | |
uint8_t bitMask; | |
for (bitMask = 0x01; bitMask; bitMask <<= 1) | |
OneWire::write_bit( (bitMask & v)?1:0); | |
if ( !power) { | |
noInterrupts(); | |
DIRECT_MODE_INPUT(); | |
DIRECT_WRITE_LOW(); | |
interrupts(); | |
} | |
} | |
void OneWire::write_bytes(const uint8_t *buf, uint16_t count, bool power /* = 0 */) { | |
for (uint16_t i = 0 ; i < count ; i++) | |
write(buf[i]); | |
if (!power) { | |
noInterrupts(); | |
DIRECT_MODE_INPUT(); | |
DIRECT_WRITE_LOW(); | |
interrupts(); | |
} | |
} | |
uint8_t OneWire::read() { | |
uint8_t bitMask; | |
uint8_t r = 0; | |
for (bitMask = 0x01; bitMask; bitMask <<= 1) | |
if ( OneWire::read_bit()) | |
r |= bitMask; | |
return r; | |
} | |
void OneWire::read_bytes(uint8_t *buf, uint16_t count) { | |
for (uint16_t i = 0 ; i < count ; i++) | |
buf[i] = read(); | |
} | |
void OneWire::select(const uint8_t rom[8]) { | |
uint8_t i; | |
write(0x55); // Choose ROM | |
for (i = 0; i < 8; i++) | |
write(rom[i]); | |
} | |
void OneWire::skip() { | |
write(0xCC); // Skip ROM | |
} | |
void OneWire::depower() { | |
noInterrupts(); | |
DIRECT_MODE_INPUT(); | |
interrupts(); | |
} | |
void OneWire::reset_search() { | |
LastDiscrepancy = 0; | |
LastDeviceFlag = FALSE; | |
LastFamilyDiscrepancy = 0; | |
for(int i = 7; ; i--) { | |
ROM_NO[i] = 0; | |
if ( i == 0) | |
break; | |
} | |
} | |
void OneWire::target_search(uint8_t family_code) { | |
ROM_NO[0] = family_code; | |
for (uint8_t i = 1; i < 8; i++) | |
ROM_NO[i] = 0; | |
LastDiscrepancy = 64; | |
LastFamilyDiscrepancy = 0; | |
LastDeviceFlag = FALSE; | |
} | |
uint8_t OneWire::search(uint8_t *newAddr) { | |
uint8_t id_bit_number; | |
uint8_t last_zero, rom_byte_number, search_result; | |
uint8_t id_bit, cmp_id_bit; | |
unsigned char rom_byte_mask, search_direction; | |
id_bit_number = 1; | |
last_zero = 0; | |
rom_byte_number = 0; | |
rom_byte_mask = 1; | |
search_result = 0; | |
// if the last call was not the last one | |
if (!LastDeviceFlag) | |
{ | |
// 1-Wire reset | |
if (!reset()) | |
{ | |
// reset the search | |
LastDiscrepancy = 0; | |
LastDeviceFlag = FALSE; | |
LastFamilyDiscrepancy = 0; | |
return FALSE; | |
} | |
// issue the search command | |
write(0xF0); | |
// loop to do the search | |
do | |
{ | |
// read a bit and its complement | |
id_bit = read_bit(); | |
cmp_id_bit = read_bit(); | |
// check for no devices on 1-wire | |
if ((id_bit == 1) && (cmp_id_bit == 1)) | |
break; | |
else | |
{ | |
// all devices coupled have 0 or 1 | |
if (id_bit != cmp_id_bit) | |
search_direction = id_bit; // bit write value for search | |
else | |
{ | |
// if this discrepancy if before the Last Discrepancy | |
// on a previous next then pick the same as last time | |
if (id_bit_number < LastDiscrepancy) | |
search_direction = ((ROM_NO[rom_byte_number] & rom_byte_mask) > 0); | |
else | |
// if equal to last pick 1, if not then pick 0 | |
search_direction = (id_bit_number == LastDiscrepancy); | |
// if 0 was picked then record its position in LastZero | |
if (search_direction == 0) | |
{ | |
last_zero = id_bit_number; | |
// check for Last discrepancy in family | |
if (last_zero < 9) | |
LastFamilyDiscrepancy = last_zero; | |
} | |
} | |
// set or clear the bit in the ROM byte rom_byte_number | |
// with mask rom_byte_mask | |
if (search_direction == 1) | |
ROM_NO[rom_byte_number] |= rom_byte_mask; | |
else | |
ROM_NO[rom_byte_number] &= ~rom_byte_mask; | |
// serial number search direction write bit | |
write_bit(search_direction); | |
// increment the byte counter id_bit_number | |
// and shift the mask rom_byte_mask | |
id_bit_number++; | |
rom_byte_mask <<= 1; | |
// if the mask is 0 then go to new SerialNum byte rom_byte_number and reset mask | |
if (rom_byte_mask == 0) | |
{ | |
rom_byte_number++; | |
rom_byte_mask = 1; | |
} | |
} | |
} | |
while(rom_byte_number < 8); // loop until through all ROM bytes 0-7 | |
// if the search was successful then | |
if (!(id_bit_number < 65)) | |
{ | |
// search successful so set LastDiscrepancy,LastDeviceFlag,search_result | |
LastDiscrepancy = last_zero; | |
// check for last device | |
if (LastDiscrepancy == 0) | |
LastDeviceFlag = TRUE; | |
search_result = TRUE; | |
} | |
} | |
// if no device found then reset counters so next 'search' will be like a first | |
if (!search_result || !ROM_NO[0]) | |
{ | |
LastDiscrepancy = 0; | |
LastDeviceFlag = FALSE; | |
LastFamilyDiscrepancy = 0; | |
search_result = FALSE; | |
} | |
for (int i = 0; i < 8; i++) newAddr[i] = ROM_NO[i]; | |
return search_result; | |
} | |
uint8_t OneWire::crc8( uint8_t *addr, uint8_t len) { | |
uint8_t crc = 0; | |
while (len--) { | |
uint8_t inbyte = *addr++; | |
for (uint8_t i = 8; i; i--) { | |
uint8_t mix = (crc ^ inbyte) & 0x01; | |
crc >>= 1; | |
if (mix) | |
crc ^= 0x8C; | |
inbyte >>= 1; | |
} | |
} | |
return crc; | |
} | |
bool OneWire::check_crc16(const uint8_t* input, uint16_t len, const uint8_t* inverted_crc, uint16_t crc) { | |
crc = ~crc16(input, len, crc); | |
return (crc & 0xFF) == inverted_crc[0] && (crc >> 8) == inverted_crc[1]; | |
} | |
uint16_t OneWire::crc16(const uint8_t* input, uint16_t len, uint16_t crc) { | |
static const uint8_t oddparity[16] = { 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 1, 1, 0 }; | |
for (uint16_t i = 0 ; i < len ; i++) { | |
uint16_t cdata = input[i]; | |
cdata = (cdata ^ crc) & 0xff; | |
crc >>= 8; | |
if (oddparity[cdata & 0x0F] ^ oddparity[cdata >> 4]) | |
crc ^= 0xC001; | |
cdata <<= 6; | |
crc ^= cdata; | |
cdata <<= 1; | |
crc ^= cdata; | |
} | |
return crc; | |
} | |
// THERMISTOR CLASS | |
class Thermistor { | |
private: | |
int _pin; | |
int _resistor; | |
int _temp_raw; | |
float _temp_k; | |
float _temp_c; | |
float _temp_f; | |
public: | |
Thermistor(int pin, int resistor); | |
void begin(void); | |
float getTemp(bool smooth); | |
float getTempF(bool smooth); | |
float getTempC(bool smooth); | |
float getTempK(bool smooth); | |
int getTempRaw(bool smooth); | |
}; | |
Thermistor::Thermistor(int pin, int resistor) { | |
_pin = pin; | |
_resistor = resistor; | |
} | |
void Thermistor::begin(void) { | |
pinMode(_pin, INPUT); | |
} | |
int Thermistor::getTempRaw(bool smooth=false) { | |
delay(1); | |
if(smooth==true) { | |
int total = 0; | |
for(int i=0; i<100; i++) { | |
total += analogRead(_pin); | |
delay(1); | |
} | |
_temp_raw = total/100; | |
} else | |
_temp_raw = analogRead(_pin); | |
return _temp_raw; | |
} | |
float Thermistor::getTempK(bool smooth=false) { | |
_temp_raw = getTempRaw(smooth); | |
_temp_k = log(((40960000/_temp_raw) - _resistor)); | |
_temp_k = 1 / (0.001129148 + (0.000234125 + (0.0000000876741 * _temp_k * _temp_k ))* _temp_k); | |
return _temp_k; | |
} | |
float Thermistor::getTempC(bool smooth=false) { | |
_temp_k = getTempK(smooth); | |
_temp_c = _temp_k - 273.15; | |
return _temp_c; | |
} | |
float Thermistor::getTempF(bool smooth=false) { | |
_temp_c = getTempC(smooth); | |
_temp_f = (_temp_c * 9.0)/ 5.0 + 32.0; | |
return _temp_f; | |
} | |
float Thermistor::getTemp(bool smooth=false) { | |
return getTempC(smooth); | |
} | |
// THERMISTOR SETUP | |
#define THERMPIN A0 // Spark Core analog input pin | |
#define THERMRES 10000 // Value of voltage divider resistor | |
Thermistor Thermistor(THERMPIN, THERMRES); | |
// DHT22 SETUP | |
#define DHTPIN D0 | |
#define DHTTYPE DHT22 | |
DHT dht(DHTPIN, DHTTYPE); | |
float dhtTempF; | |
float dhtTempC; | |
float dhtHumidity; | |
uint32_t dhtTimeout; | |
// DS18B20 SETUP | |
OneWire one = OneWire(D1); | |
// LED COLORS | |
uint8_t colorRed[3] = { 255, 0, 0 }; | |
uint8_t colorOrange[3] = { 255, 165, 0 }; | |
uint8_t colorYellow[3] = { 255, 255, 0 }; | |
uint8_t colorGreen[3] = { 0, 255, 0 }; | |
uint8_t colorBlue[3] = { 0, 0, 255 }; | |
uint8_t colorPurple[3] = { 128, 0, 128 }; | |
uint8_t colorWhite[3] = { 255, 255, 255 }; | |
uint8_t colorPink[3] = { 255, 192, 203 }; | |
char lastCommand[64] = "NONE"; | |
void setup() { | |
dht.begin(); | |
Thermistor.begin(); | |
// Cloud functions | |
Spark.function("fnrouter", fnRouter); | |
// Cloud variables | |
Spark.variable("lastCommand", &lastCommand, STRING); | |
// Get initial reading to flush out bad stuff | |
delay(2000); | |
dht.readHumidity(); | |
dht.readTemperature(); | |
dhtTimeout = millis()/1000; | |
} | |
void loop() { | |
// Do nothing | |
} | |
float oneTemp() { | |
uint8_t rom[8]; | |
uint8_t resp[9]; | |
// Get the ROM address | |
one.reset(); | |
one.write(0x33); | |
one.read_bytes(rom, 8); | |
// Get the temp | |
one.reset(); | |
one.write(0x55); | |
one.write_bytes(rom,8); | |
one.write(0x44); | |
delay(10); | |
one.reset(); | |
one.write(0x55); | |
one.write_bytes(rom, 8); | |
one.write(0xBE); | |
one.read_bytes(resp, 9); | |
byte MSB = resp[1]; | |
byte LSB = resp[0]; | |
float tempRead = ((MSB << 8) | LSB); //using two's compliment | |
float TemperatureSum = tempRead / 16; | |
return TemperatureSum; | |
} | |
void dhtPoll() { | |
if((dhtTimeout+millis()/1000)>2) { | |
dhtTempF = dht.readTemperature(true); | |
dhtTempC = dht.readTemperature(false); | |
dhtHumidity = dht.readHumidity(); | |
dhtTimeout = millis()/1000; | |
} | |
} | |
int fnRouter(String command) { | |
command.trim(); | |
command.toUpperCase(); | |
command.toCharArray(lastCommand, 64); | |
blinkLedRapid(colorOrange); | |
if(command.equals("DHTHUMIDITY")) { | |
dhtPoll(); | |
return dhtHumidity*100; | |
} else if(command.equals("DHTTEMP") || command.equals("DHTTEMPF")) { | |
dhtPoll(); | |
return dhtTempF*100; | |
} else if(command.equals("DHTTEMPC")) { | |
dhtPoll(); | |
return dhtTempC*100; | |
} else if(command.equals("THERMTEMPK")) | |
return (Thermistor.getTempK()*100); | |
else if(command.equals("THERMTEMPC")) | |
return (Thermistor.getTempC()*100); | |
else if(command.equals("THERMTEMP") || command.equals("THERMTEMPF")) | |
return (Thermistor.getTempF(true)-5)*100; | |
else if(command.equals("ONETEMPC")) | |
return oneTemp()*100; | |
else if(command.equals("ONETEMP") || command.equals("ONETEMPF")) | |
return ((oneTemp() * 9.0) / 5.0 + 32.0)*100; | |
else if(command.equals("SECONDS")) | |
return millis()/1000; | |
else if(command.equals("MILLIS")) | |
return millis(); | |
else if(command.equals("LEDRED")) | |
return blinkLed(colorRed); | |
else if(command.equals("LEDBLUE")) | |
return blinkLed(colorBlue); | |
else if(command.equals("LEDGREEN")) | |
return blinkLed(colorGreen); | |
else if(command.equals("LEDWHITE")) | |
return blinkLed(colorWhite); | |
else if(command.equals("LEDYELLOW")) | |
return blinkLed(colorYellow); | |
else if(command.equals("LEDORANGE")) | |
return blinkLed(colorOrange); | |
else if(command.equals("LEDPURPLE")) | |
return blinkLed(colorPurple); | |
else if(command.equals("LEDPINK")) | |
return blinkLed(colorPink); | |
else if(command.equals("D7BLINK")) | |
return blinkD7(); | |
else { | |
blinkLedRapid(colorRed); | |
return -1000; | |
} | |
} | |
int blinkLed(uint8_t color[3]) { | |
RGB.control(true); | |
for(int i=0; i<3; i++) { | |
RGB.color(color[0], color[1], color[2]); | |
delay(250); | |
RGB.color(0, 0, 0); | |
delay(250); | |
} | |
RGB.control(false); | |
return 1; | |
} | |
int blinkLedRapid(uint8_t color[3]) { | |
RGB.control(true); | |
for(int i=0; i<10; i++) { | |
RGB.color(color[0], color[1], color[2]); | |
delay(25); | |
RGB.color(0, 0, 0); | |
delay(25); | |
} | |
RGB.control(false); | |
return 1; | |
} | |
int blinkD7() { | |
pinMode(D7, OUTPUT); | |
for(int i=0; i<3; i++) { | |
digitalWrite(D7, HIGH); | |
delay(250); | |
digitalWrite(D7, LOW); | |
delay(250); | |
} | |
return 1; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment