Calculating Sunrise and Sunset on Arduino (or other microcontroller)

Knowing the hours of sunset and sunrise may be handy in a variety of situations, an automated chicken coop door might be only one example.

There are several ways to get the proper times: a lookup table in EEPROM, the Timelord library or one of its successors, the Dusk2Dawn library, a rather complicated calculation including the Julian calender, or a fairly simple approximation that I will discuss here.

This method uses the average of the earliest and latest sunset and then for any given day  adds or subtracts a certain amount of time with a maximum of half  of the difference between the earliest and latest sunrise.

Rob Tillaert discusses the method here. It presumes that the sunrise time follows a (co)sinoidal function. I will try to visualize it with a simple example:

Say that on June 23 the earliest sunrise of the year occurs at 4am, and that the latest sunrise of the year occurs at 23 December at 6 am.

Then you know that on any other day the sunrise is between 4 and 6 am. If you take the average that is 5 am, then you know that every other sunrise that year is either 0-1 hr later than 5 am or 0-1 hr earlier than 5 am.

It is the latter that is captured in the formula:

t=avg+0.5Δ*cos((doy+8)/58.09)

  • avg is average sunrise time, in minutes since midnight
  • Δ the difference between the earliest and latest sunrise time
  • doy is the day of the year
  • the 8 is there because we start on the wintersolstice: 23 December is 8 days before jan 1
  • 58.09 is 365/2π. That is necessary because the cosinusfunction has max 2π as input.

If you live in a DST zone, the earliest sunrise wil be under DST, however you need the non-DST corrected time: the sun knows no DST. Calculate firstm then add DST later

For my location the earliest and latest sunrise are:

earliest sunrise is at 4.19 am
latest sunrise is at 8.51
in order to use them in our equation, we have to calculate them in minutes past midnight:
4.19= 4×60+19=259
8.51= 8*60+51=531
The average is (259+531)/2=395
the difference or delta is 531-259=272. We need half of that which is 137.
The equation then becomes:

395+137*cos((doy+8)/58.09)

To check the accuracy of the approximation, I plotted the actual sunrise times (blue curve) against the calculated sunrise time (red curve).

As it shows, the first half of the year is a perfect fit, the second half of the year seems to follow a more linear curve with the max deviation being 20 minutes, that may or may not be accurate enough for your project. With the aid of this curve though I could opt for a linear approximation for the 2nd half of the year.

For sunset we can practically use the same formula, be it that we now have to subtract the variable part rather than add it.
For my location the sunset is as follows:
latest: 22:07 =1327
Earliest: 16:27= 987
avg=2287/2=1144
delta=1327-987=340 ->170
sunset=1144-170*cos((doy+8)/58.09)

That gives the following graph:

This time I didnt bother to enter all the  real sunset times, but it is clearly visible that there is a reasonable fit that could maybe be enhanced a bit by shifting it slightly more to left or decreasing the delta a bit. Again Red graph is the calculated sunset, the blue is the actual sunset. None of the graphs has been corrected for DST.

A procedure for the Arduino would look as follows:
Where DST is a byte indicating whether DST is active (1)  or not active (0).
The day of the year I pull from my RTC library but it can also be calculated as follows:
int(((month-1)*30.5)+dayOfMonth)  (that is an approximation though)

The sunrise and sunset are both given in minutes after midnight. The hour and minutes of the sunrise (and sunset) can be calculated by:
hour=sunrise/60
minute=sunrise%60

Advertisements

MQTT with the W5100 Ethernetshield

New code added

In a previous post I discussed the use of an old ENC28J60 ethernetshield for an MQTT node. The biggest setback of the ENC28J60 shield is that it uses a lot of memory. When using the newer W5100 Ethernetshield, there is a bit more room to play with. So here is a simple framework  for an MQTT node that doesnt’t only publish, but also reacts to simple commands that come in with a subscription.

MQTT-Spy output
MQTT-Spy output
/*
          Arduino UNO with W5100 Ethernetshield or  W5100 Ethernet module, used as MQTT client
          It will connect over Wifi to the MQTT broker and controls a digital output (LED, relay)
          and gives the Temperature and Humidity, as well as the state of some switches
          The topics have the format "home/br/sb" for southbound messages and  "home/nb" for northbound messages
          Southbound are messages going to the client, northbound are messages coming from the client
          As the available memory of a UNO  with Ethernetcard is limited, I have kept the topics short
          Also, the payloads  are kept short
          The Northbound topics are
          home/br/nb/temp  for temperature
          home/br/nb/humid  for humidity
          home/br/nb/deur  for a door switch
          home/br/nb/l for  the lightintensity
          home/br/nb/pr  for the status of a PIR sensor
          home/br/nb/ip showing the IP number of the client
          home/br/nb/relay showing the relaystate

          There is only one southbound topic:
          home/br/sb
          The payload here determines the action:
          0 -Switch the relay off
          1-Switch the  relay on
          2-Publish the IP number of the client
          3 Ask for the relaystate REMOVED

          On Startup, the Client publishes the IP number

*/
#include "Ethernet.h"
#include "PubSubClient.h"
#include "DHT.h"
//kennelijk  geeft update van DHT sensor library boven 1.2.1 een fout
#define CLIENT_ID       "Hal"
//#define TOPIC           "temp"
#define PUBLISH_DELAY   3000
#define PUB_TOPIC "my_username/f/temperature" //Adafruit dashboard
#define PUB_TOPIC_h "my_username/f/humidity" //Adafruit dashboard
#define DHTPIN          3
#define DHTTYPE         DHT11
#define ledPin 13
#define relayPin 8
String ip = "";
bool statusKD = HIGH;
bool statusBD = HIGH;
bool statusGD = HIGH;
bool relaystate = LOW;
bool pir = LOW;
bool startsend = HIGH;
int lichtstatus;
uint8_t mac[6] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x06};

EthernetClient ethClient;
PubSubClient mqttClient;
DHT dht(DHTPIN, DHTTYPE);

long previousMillis;

void setup() {
  pinMode(4, INPUT_PULLUP);
  pinMode(5, INPUT_PULLUP);
  pinMode(6, INPUT_PULLUP);
  pinMode(7, INPUT);
  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(relayPin, OUTPUT);

  // setup serial communication

  Serial.begin(9600);
  while (!Serial) {};
  Serial.println(F("MQTT Arduino Demo"));
  Serial.println();

  // setup ethernet communication using DHCP
  if (Ethernet.begin(mac) == 0) {
    //Serial.println(F("Unable to configure Ethernet using DHCP"));
    for (;;);
  }

  Serial.println(F("Ethernet configured via DHCP"));
  Serial.print("IP address: ");
  Serial.println(Ethernet.localIP());
  Serial.println();
  /*
    Serial.println(Ethernet.localIP()[0]);
    Serial.println(Ethernet.localIP()[1]);
    Serial.println(Ethernet.localIP()[2]);
    Serial.println(Ethernet.localIP()[3]);
  */
  ip = String (Ethernet.localIP()[0]);
  ip = ip + ".";
  ip = ip + String (Ethernet.localIP()[1]);
  ip = ip + ".";
  ip = ip + String (Ethernet.localIP()[2]);
  ip = ip + ".";
  ip = ip + String (Ethernet.localIP()[3]);
  //Serial.println(ip);

  // setup mqtt client
  mqttClient.setClient(ethClient);
  //mqttClient.setServer(mqttServer, 1883);
  // mqttClient.setServer("test.mosquitto.org", 1883);
  //  mqttClient.setServer( "raspberrypi.local",1883);
  //mqttClient.setServer("io.adafruit.com",1883);
  mqttClient.setServer( "192.168.1.102", 1883);
  //Serial.println(F("MQTT client configured"));
  mqttClient.setCallback(callback);
  // setup DHT sensor
  dht.begin();
  Serial.println(F("DHT sensor initialized"));

  Serial.println();
  Serial.println(F("Ready to send data"));
  previousMillis = millis();
  mqttClient.publish("home/br/nb/ip", ip.c_str());
}

void loop() {

  statusBD = digitalRead(4);// FrontdoorSwitch
  statusGD = digitalRead(5);// Garagedoor Switch
  statusKD = (digitalRead(6));//LivingRoom Switch

  lichtstatus = analogRead(A0);//Reads an LDR
  pir = digitalRead(7);//Reads a PIR sensor
  relaystate = digitalRead(relayPin);// Reads the state of a relay

  // it's time to send new data?
  if (millis() - previousMillis > PUBLISH_DELAY) {
    sendData();
    previousMillis = millis();

  }

  mqttClient.loop();
}

void sendData() {

  char msgBuffer[20];
  float h = dht.readHumidity();
  float t = dht.readTemperature();
  Serial.print("Temperature: ");
  Serial.print(t);
  Serial.println("oC");
  Serial.print("Humidity: ");
  Serial.print(h);
  Serial.println("%");
  Serial.print("Relay is: ");
  Serial.println((relaystate == LOW) ? "OPEN" : "CLOSED");
  if (mqttClient.connect(CLIENT_ID)) {
    mqttClient.publish("home/br/nb/temp", dtostrf(t, 6, 2, msgBuffer));
    mqttClient.publish("home/br/nb/humid", dtostrf(h, 6, 2, msgBuffer));
    mqttClient.publish("home/br/nb/deur", (statusBD == HIGH) ? "OPEN" : "CLOSED");
    mqttClient.publish("home/br/nb/garage", (statusGD == HIGH) ? "OPEN" : "DICHT");
    mqttClient.publish("home/br/nb/bel", (statusKD == HIGH) ? "OPEN" : "CLOSED");
    mqttClient.publish("home/br/nb/l", dtostrf(lichtstatus, 4, 0, msgBuffer));
    mqttClient.publish("home/br/nb/p", (pir == HIGH) ? "OPEN" : "CLOSED");
    mqttClient.publish("home/br/nb/relay", (relaystate == LOW) ? "OPEN" : "CLOSED");
    mqttClient.subscribe("home/br/sb");
    if (startsend) {
     // mqttClient.publish("home/br/nb/relay", (relaystate == LOW) ? "OPEN" : "CLOSED");
      mqttClient.publish("home/br/nb/ip", ip.c_str());
      startsend = LOW;
    }
  }
}

void callback(char* topic, byte* payload, unsigned int length) {
  char msgBuffer[20];
  // I am only using one ascii character as command, so do not need to take an entire word as payload
  // However, if you want to send full word commands, uncomment the next line and use for string comparison
   //payload[length] = '\0';            // terminate string with '0'
  //String strPayload = String((char*)payload);  // convert to string
  // Serial.println(strPayload); //can use this if using longer southbound topics
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");//MQTT_BROKER
  for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);
  }
  Serial.println();
  Serial.println(payload[0]);

  // Examine only the first character of the message
  if (payload[0] == 49)             // Message "1" in ASCII (turn output ON)
  {
    digitalWrite(LED_BUILTIN, HIGH);    //
    digitalWrite(relayPin, HIGH);
  } else if (payload[0] == 48)      // Message "0" in ASCII (turn output OFF)
  {
    digitalWrite(relayPin, LOW);     //
    digitalWrite(LED_BUILTIN, LOW);
  } else if (payload[0] == 50)
  {
    mqttClient.publish("home/br/nb/ip", ip.c_str());// publish IP nr
  } else {
    Serial.println("Unknown value");
    mqttClient.publish("home/br/nb", "Syntax Error");
  }

}

You will find the full code for download here.

Edit 
I altered the above code a bit so it takes ON/OFF/READ commands rather than just numbers.

It now looks like this:

/*
Arduino UNO with W5100 Ethernetshield or W5100 Ethernet module, used as MQTT client
It will connect over Wifi to the MQTT broker and controls a digital output (LED, relay)
and gives the Temperature and Humidity, as well as the state of some switches
The topics have the format "home/br/sb" for southbound messages and "home/nb" for northbound messages
Southbound are messages going tomq the client, northbound are messages coming from the client
As the available memory of a UNO with Ethernetcard is limited, I have kept the topics short
Also, the payloads are kept short
The Northbound topics are
home/br/nb/temp for temperature
home/br/nb/humid for humidity
home/br/nb/deur for a door switch
home/br/nb/l for the lightintensity
home/br/nb/pr for the status of a PIR sensor
home/br/nb/ip showing the IP number of the client
home/br/nb/relay showing the relaystate

There is only one southbound topic:
home/br/sb
The payload here determines the action:
OFF -Switch the relay off
ON-Switch the relay on
READ Ask for the relaystate

*/
#include "Ethernet.h"
#include "PubSubClient.h"
#include "DHT.h"
#define CLIENT_ID "Hal"
#define PUBLISH_DELAY 30000
#define DHTPIN 3
#define DHTTYPE DHT11
#define ledPin 13
#define relayPin 8
String ip = "";
bool statusKD = HIGH;
bool statusBD = HIGH;
bool statusGD = HIGH;
bool relaystate = LOW;
bool pir = LOW;
bool startsend = HIGH;
int lichtstatus;
uint8_t mac[6] = {0x00, 0x01, 0x02, 0x03, 0x04, 0x06};

EthernetClient ethClient;
PubSubClient mqttClient;
DHT dht(DHTPIN, DHTTYPE);

long previousMillis;

void setup() {
pinMode(4, INPUT_PULLUP);
pinMode(5, INPUT_PULLUP);
pinMode(6, INPUT_PULLUP);
pinMode(7, INPUT);
pinMode(LED_BUILTIN, OUTPUT);
pinMode(relayPin, OUTPUT);
digitalWrite(relayPin, LOW);
digitalWrite(LED_BUILTIN,HIGH);

// setup serial communication

Serial.begin(9600);
while (!Serial) {};
Serial.println(F("MQTT Arduino Demo"));
Serial.println();

// setup ethernet communication using DHCP
if (Ethernet.begin(mac) == 0) {
//Serial.println(F("Unable to configure Ethernet using DHCP"));
for (;;);
}

Serial.println(F("Ethernet configured via DHCP"));
Serial.print("IP address: ");
Serial.println(Ethernet.localIP());
Serial.println();

ip = String (Ethernet.localIP()[0]);
ip = ip + ".";
ip = ip + String (Ethernet.localIP()[1]);
ip = ip + ".";
ip = ip + String (Ethernet.localIP()[2]);
ip = ip + ".";
ip = ip + String (Ethernet.localIP()[3]);
//Serial.println(ip);

// setup mqtt client
mqttClient.setClient(ethClient);
mqttClient.setServer( "192.168.1.103", 1883);
//Serial.println(F("MQTT client configured"));
mqttClient.setCallback(callback);
// setup DHT sensor
dht.begin();
Serial.println(F("DHT sensor initialized"));

Serial.println();
Serial.println(F("Ready to send data"));
previousMillis = millis();
mqttClient.publish("home/br/nb/ip", ip.c_str());
}

void loop() {

statusBD = digitalRead(4);// FrontdoorSwitch
statusGD = digitalRead(5);// Garagedoor Switch
statusKD = (digitalRead(6));//LivingRoom Switch

lichtstatus = analogRead(A0);//Reads an LDR
pir = digitalRead(7);//Reads a PIR sensor
relaystate = digitalRead(relayPin);// Reads the state of a relay

// it's time to send new data?
if (millis() - previousMillis > PUBLISH_DELAY) {
sendData();
previousMillis = millis();
}

mqttClient.loop();
}

void sendData() {
char msgBuffer[20];
float h = dht.readHumidity();
float t = dht.readTemperature();
Serial.print("Temperature: ");
Serial.print(t);
Serial.println("oC");
Serial.print("Humidity: ");
Serial.print(h);
Serial.println("%");
Serial.print("Relay is: ");
Serial.println((relaystate == LOW) ? "OPEN" : "CLOSED");
if (mqttClient.connect(CLIENT_ID)) {
mqttClient.publish("home/br/nb/temp", dtostrf(t, 6, 2, msgBuffer));
mqttClient.publish("home/br/nb/humid", dtostrf(h, 6, 2, msgBuffer));
mqttClient.publish("home/br/nb/deur", (statusBD == HIGH) ? "OPEN" : "CLOSED");
mqttClient.publish("home/br/nb/garage", (statusGD == HIGH) ? "OPEN" : "DICHT");
mqttClient.publish("home/br/nb/bel", (statusKD == HIGH) ? "OPEN" : "CLOSED");
mqttClient.publish("home/br/nb/l", dtostrf(lichtstatus, 4, 0, msgBuffer));
mqttClient.publish("home/br/nb/p", (pir == HIGH) ? "OPEN" : "CLOSED");
mqttClient.publish("home/br/nb/relay", (relaystate == LOW) ? "OPEN" : "CLOSED");
mqttClient.publish("home/br/nb/ip", ip.c_str());
mqttClient.subscribe("home/br/sb/relay");
if (startsend) {
// mqttClient.publish("home/br/nb/relay", (relaystate == LOW) ? "OPEN" : "CLOSED");
mqttClient.publish("home/br/nb/ip", ip.c_str());
startsend = LOW;
}
}
}

void callback(char* topic, byte* payload, unsigned int length) {
Serial.print("Message arrived [");
Serial.print(topic);
Serial.print("] ");//MQTT_BROKER

for (int i = 0; i < length; i++) {
Serial.print((char)payload[i]);
}
Serial.println();
Serial.println(payload[0]);

if (strncmp((const char*)payload, "ON", 2) == 0) {
digitalWrite(ledPin, HIGH); //
digitalWrite(relayPin, HIGH);
}
if (strncmp((const char*)payload, "OFF", 3) == 0) {
digitalWrite(relayPin, LOW); //
digitalWrite(ledPin, LOW);
}
if (strncmp((const char*)payload, "READ", 4) == 0) {
mqttClient.publish("home/br/nb/relay", (relaystate == LOW) ? "OPEN" : "CLOSED");
}
}

It can be found here.
Apparently the 1st code simple I had published sometimes didn’t keep the relay state. New code does not have that problem.
The code has a number of print statements. Once it is hooked up to the network it might not be very useful to have those anymore. Commenting them out will make more space available

Setting up a local MQTT broker on the Raspberry Pi

On the web there are a ton of instructions and how to’s on how to do this, but I found  it easiest to just  issue two commands on Raspian Jessie:
sudo apt-get update
sudo apt-get install mosquitto mosquitto-clients python-mosquitto

then to test if it was all working, I opened 2 ssh terminals to my raspberry with:
ssh pi@192.168.1.102  (the latter being the ip nr from my raspberry)
and then in one of those terminals I entered:
mosquitto_sub -d -t hello/world
this made the terminal I will call Terminal 1 subscribe to the topic “hello/world”
in the other ssh terminal window (Terminal 2) I entered
mosquitto_pub -d -t hello/world -m "Greetings from Terminal2"
and immediately I got that message published in Terminal 1
(actually you don’t need the ‘-d’ option. That is just for diagnostics)
So I knew my local Mosquitto broker was working, at least within one machine, the raspberry on which it was installed. Time to check if it also worked on other machines. To do that I opened a third terminal on my desktop that didnt ssh to the raspberry but just gave a command line to the machine I was working on (a regular Linux desktop).

Before I could have that machine subscribe to an MQTT topic, I first had to install the MQTT client with:
sudo apt-get install mosquitto-clients

when that was done I entered:
mosquitto_sub -h 192.168.1.102 -t hello/world

mosquitto-terminalNow when I published a message on terminal2 (thats the raspberry) it got published on terminal1 (that same raspberry) and on terminal3 (a regular desktop), so now I knew everything was hunky dory.
However, having to use terminal command lines to check your MQTT broker is not the most convenient. I can advise everybody who works with MQTT to install MQTT-spy. That is a jar file that basically is a publisher and a client that keeps track of MQTT messages on your network.

It comes pre-configured with 3 public brokers but adding your local broker is very simple:
mqtt-localAfter starting MQTT-spy go to  ‘Connections-New Connection” Fill out a name for your connection and under the ‘connectivity tab’ add (in my case): 192.168.1.102:1883  with 1883 being the  standard MQTT port.
Then go to the ‘other’tab and check ‘auto subscribe when opened’.
Now in the main window add a subscription tab called ‘hello/world’ and republish  the messagemqttspy-3 from Terminal2: it should appear in the receive window of mqtt-spy. Vice versa, if  you publish a message from within mqtt spy, it will appear on terminal 1 also

Monitoring LiPo battery voltage with Wemos D1 minibattery shield and Thingspeak

There are a million reasons why you would want to monitor the Battery voltage of  your Battery fed ESP8266. I will illustrate it with a Wemos D1 mini and the Battery shield

batteryshield
Wemos D1 Mini Battery shield

I am using a small 720 mAh LiPo cel. If I just leave the Wemos access the internet continuously it will last 6.5 hours, but for this example I will put the Wemos in Deepsleep for a minute, then read the battery voltage and upload that to Thingspeak.
You only need to make a few connections:
First, connect RST with GPIO16 (that is D0 on the Wemos D1 mini). This is needed to let the chip awake from sleep.
Then connect the Vbat  through a 100k resistor to A0.

So why a 100 k resistor?

Well the Wemos D1 mini already has an internal voltage divider  that connects the A0 pin to the ADC of the ESP8266 chip. This is a 220 k resistor over a 100 k resistor

Wemos D1 Internal Voltage divider
Wemos D1 Internal Voltage divider

By adding a 100k , it will in fact be a total resistance  of 100k+220k+100k=420k.
So if the Voltage of a fully loaded Cell would be 4.2 Volt, the ADC of the ESP8266 would get 4.2 * 100/420= 1 Volt

1 Volt is the max input to the ADC and will give a Raw reading of 1023.

The True voltage  then can be calculated by:
raw = AnalogRead(A0);voltage =raw/1023;
voltage =4.2*voltage;
Ofcourse you could also do that in one step, but I like to keep it easy to follow.

Wemos Battery monitoring
Wemos Battery monitoring

If you do use this possibility, do realise that the resistors drain the battery as well with a constant 10uA (4.2V/420 000ohm). The powerconsumption of an ESP8266 in deepsleep is about 77uA. With the battery monitor this would be 87uA, which is a sizeable increase. A solution could be to close off the Vbat to the A0 with a transistor, controlled from an ESP8266 pin

A program could look like this:

/*
 * Wemos battery shield, measure Vbat
 * add 100k between Vbat and ADC
 * Voltage divider of 100k+220k over 100k
 * gives 100/420k
 * ergo 4.2V -> 1Volt
 * Max input on A0=1Volt ->1023
 * 4.2*(Raw/1023)=Vbat
 */

// Connect RST en gpio16 (RST and D0 on Wemos)
#include <ESP8266WiFi.h>
unsigned int raw=0;
float volt=0.0;
// Time to sleep (in seconds):
const int sleepTimeS = 60;

void setup() {
  Serial.begin(115200);
  Serial.println("ESP8266 in normal mode");
  const char* ssid     = "YourSSID";
  const char* password = "YourPW";
  const char* host = "api.thingspeak.com";
  const char* writeAPIKey="YourAPIkey";
  // put your setup code here, to run once:
  pinMode(A0, INPUT);
  raw = analogRead(A0);
  volt=raw/1023.0;
  volt=volt*4.2;
//  Connect to WiFi network
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
  delay(500);
  }
  String v=String(volt);// change float into string
  // make TCP connections
  WiFiClient client;
  const int httpPort = 80;
  if (!client.connect(host, httpPort)) {
    return;
  }
  String url = "/update?key=";
  url += writeAPIKey;
  url += "&field6=";// I had field 6 still free that's why
  url += String(volt);
  url += "\r\n";
 
// Send request to the server
  client.print(String("GET ") + url + " HTTP/1.1\r\n" +
                 "Host: " + host + "\r\n" +
                 "Connection: close\r\n\r\n");

 //Sleep
   Serial.println("ESP8266 in sleep mode");
   ESP.deepSleep(sleepTimeS * 1000000);              
}

void loop() {
  //all code is in the Setup
}

The new battery shield
There now is a new version (V1.2.0) of the battery shield that has an inbuilt resistor connecting A0 to the battery, through Jumer J2 (‘Jumper’ being a big word for 2 solderpads), so if you want to measure the battery voltage, all you need to do is to put some solder connecting J2
However, rather than a 100k resistor, a 130k resistor was used. The voltage divider thus becomes 100/(130+220+100), so for a full reading of 1023 (=1Volt on A0) a total of  (1/100k)*(130+220+100)=4.5Volt would be necessary.
In reality the Lipo cell will not give off 4.5Volt.

So your touch sensor is not working?

sensorWe have all experienced it, you buy something at Aliexpress. It arrives and you confirm receipt before you have time to test everything and then when you finally get around to that… there is a problem.
That happened to me with a TTP223B capacitive touch sensor. Whatever I tried, the output remained low. Slightly frustrated I was looking at the rather simple board and thought that there really couldn’t be much wrong with it.
ttp223-icFound a datasheet of the TTP223B ic that is on this module and started measuring. Well to make a long story short, the input pin (pin 3) seemed to have no connection with the sensorplate. When I would just touch the input pin, it switched very well. According to an application note in the datasheet capacitor C1 should be between  the input and  the ground and as it should be connected it also should be connected to the  sensorplate, which in fact it was. Turns out pin 3 was not connected to anything. A small wire that I soldered between the top of C1 and  pin 3 remedied everything and after that the sensor worked wonder well.
On checking the feedback of people who ordered this sensor, I noticed many experienced the same problem. No doubt the manufacturer (not perse the seller) must have known about this.

ttp233

Update two channels (different API’s) in Thingspeak

Uploading to two different channels in Thingspeak is fairly easy and can be done with the code below.
The code does close connection in between the uploads, perhaps that isnt necessary but I had some trouble getting it to work without closing the connection,not saying it cant be done

void  sendDataToThingspeak(void)
{

// make TCP connections
  WiFiClient client;
  const int httpPort = 80;
  if (!client.connect(thingspeakServer, httpPort)) {
    return;
  }

  String url = "/update?key=";
  url += writeAPIKey;
  url += "&field1=";
  url += String(humidity);//
  url += "&field2=";
  url += String(humiditySetPoint );//
  url += "&field3=";
  url += String(humidifier);
  url += "&field4=";
  url += String(autoMode); //
  url += "&field5=";
  url += String(t);
  url += "\r\n";

  // Send request to the server
  client.print(String("GET ") + url + " HTTP/1.1\r\n" +
               "Host: " + host + "\r\n" +
               "Connection: close\r\n\r\n");
               
  // Second channel            

//-------- Make new connection
 if (!client.connect(thingspeakServer, httpPort)) {
    return;
  }
  url = "/update?key=";
  url += writeAPIKey2;
  url += "&field1=";
  url += String(value1);// 
  url += "&field2=";
  url += String(value2 );// 
  url += "\r\n";
    client.print(String("GET ") + url + " HTTP/1.1\r\n" +
               "Host: " + host + "\r\n" +
               "Connection: close\r\n\r\n");
 Serial.println("Thingspeak");
}

BruteForce code finding in an RGB Infrared LEDstrip

irrgbledNeed:

  • Arduino.
  • IR Infrared RGB lightstrip
  • IR LED 940nm
  • resistor 560ohm

If you have one of those RGB LED strips that come with those standard 24 or 44 key transmitters and you need the IRcodes so you can send them from an Arduino to control your lightstrip, it is easy to use one of the IR libraries, such as that of Ken Shirrif and use the receive sketch to sniff the codes from the receiver. But what if you lost your transmitter or for some reason the receive sketch doesnt recognize it. Well, then there is another possibiliuty: BruteForce

As I understood these IR units usually work with the NEC protocol. I will not bore you with the sync bits and timing and the stopbits as we have the library to take care of that. The essence of the NEC protocol is a 32 bit pulse-train, in which the first byte (8bits) is the address, the second byte is the inverse address, the 3rd byte is the command and the 4th byte the inverse command. With inverse I mean that in binary form all the 1’s and 0’s are switched. So if a specific command would be “10101011” then the inverse is “01010100”. In the mean time I had come across an instructable (but cant find it anymore) of someone who wrote a program to generate codes for his IR controlled lamp). He generated his own 38kHz signal, something I didnt want to do, but it gave me the idea to not sniff my transmitter, but to scan the ledstrip bij sending possible codes to it. Now 32 bits seems like a lot of possible codes but it isnt. Remember how the NEC protocol was build: 1 address byte and 1 control byte. As I had come to understand the address byte didnt really matter (it does though), at most I would have to send 256 codes and single out the 24 (and hopefully more)

/* ********************************
This code quickly checks what codes will work with an IR RGB LEDstrip.
Adapt the delay for a quick scan or for precise jot down of the  code and its effect
02 november 2016
by DIY_bloke
********************************/ 

unsigned long command = 0;
#include  //Ken Shirriff's IRremote.h
IRsend irsend;

byte  al, ar, cl, cr;// the address and command byte and their inverse
unsigned int a, c;// the complete address and command byte
unsigned long totaal = 0L;// the 32 byte long to send to plug into the NEC protocol

void setup() {
  Serial.begin(9600);
  Serial.println("Arduino Ready");
}

void loop() {
  for (al = 0; al < 255; al++)   //we start with address 0
  {
Serial.println(al);
    for (cl = 0x0; cl < 255; cl++) // and with command 0. We first loop through the commands     {       doen(al, cl);        totaal = combineint(c, a);        Serial.print("Address> ");
       Serial.print(al,DEC);
       Serial.print(" Command> ");
       Serial.print(cl,DEC);
       Serial.print("> ");
       //Serial.print(c);
       Serial.print(" Total ");
       Serial.println(totaal,HEX);

      irsend.sendNEC(totaal, 32);
      delay(100); // Optional
    }
  }
}
//makes a long from two integers
unsigned long combineint (unsigned int rechts, unsigned long links)
{
  unsigned long value2 = 0L;
  value2 = links << 16;
  value2 = value2 | (rechts);
  return value2;
}
unsigned int doen(byte ag, byte cg)
{
  ar = ag ^ 0xFF;
  cr = cg ^ 0xFF;
  a = 256 * ag + ar;
  c = cg << 8 | cr;
}

int Combine(byte b1, byte b2)
{
  int combined = b1 << 8 | b2;
  return combined;
}

The program is fairly simple. It defines byte variables for the address and the command It inverts the address and the command so then there are 4 bytes.

It first combines the address bytes and the command bytes each to 1 integer and then it combines the address integer and the command integer to a long variable. Actually this proved to be the hardest part as I encountered some wrong values as I overlooked some variables that needed to be unsigned (Thanks Yoh there for putting me on track again).

Once those 4 bytes are a 32 bit Long, that is fed into the NEC protocol of the IRremote library. The address loops from 0 to 255 and once that is done the address byte increases with 1 and it starts allover again, so there are 256² =65536 possibilities to go through to find 24 codes.

Now obviously that would be a worst case scenario. But even then that can be rather quick. So once you have attached an IR LED to pin 3 (either through a resistor or a decent driver) power up your RGB strip (bij plugging it in the grid) and use your remote to switch it ON. The program will eventually find the ON code, but it would be a pity if that was the last code because then you have missed the activity of the LED strip. There is a delay in the code that you begin to set for 50msec. then start the code. The program then starts going through all commands and address possibilities. Now suppose the 24 codes would all be huddled together in the last 25 spaces of the 65536 possibilities. then it would take you 65512 *50msec= 55min to get to your codes.

That may seem long, but you dont have to do watch. The only thing you need to do is once you see your RGB ledstrip change color, check the serial monitor to see what address range you are at. Then stop the program, change the outer (address) loop to start from that address and set the delay to say 1 second and then note what code causes what effect. Now maybe you are 1 or 2 positions off, but if you know just whereabout it is just try sending the ones around it. I was lucky, ALL my codes where on address page 1 and then it took me about 5 minutes to find them all.

Also, remember that when the IR LED on your arduino is spitting out codes every 50ms your remote wont be able to do much anymore, so dont be surprised if it suddenly seems to ‘not work’ anymore. Cover the IR LED on the arduino and you will see your remote come alive again

Just one remark on IR LED’s
In Ken’s library discussion, he uses a 1 k resistor to directly drive an IR LED from pin 3 of the Arduino. That is definitely possible. However, it will not reach far. IR LEDś can easily be fed with 100mA as they only get small pulses. Obviously an arduino pin is not suitable for that.
a simple transistor driver for 5 Volt, with a series resistor of 33 ohm will usually do nicely. Be sure to check it for your specific situation.