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"="" northbound="" are="" going="" tomq="" the="" client,="" coming="" from="" client="" as="" available="" memory="" of="" a="" uno="" with="" ethernetcard="" is="" limited,="" i="" have="" kept="" topics="" short="" also,="" payloads="" nb="" temp="" temperature="" humid="" humidity="" deur="" door="" switch="" l="" lightintensity="" pr="" status="" pir="" sensor="" ip="" showing="" number="" relay="" relaystate="" there="" only="" one="" topic:="" sb="" payload="" here="" determines="" action:="" off="" -switch="" on-switch="" on="" read="" ask="" *="" #include="" "ethernet.h"="" "pubsubclient.h"="" "dht.h"="" #define="" client_id="" "hal"="" publish_delay="" 30000="" dhtpin="" 3="" dhttype="" dht11="" ledpin="" 13="" relaypin="" 8="" string="" ;="" bool="" statuskd="HIGH;" statusbd="HIGH;" statusgd="HIGH;" 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,="" pinmode(6,="" pinmode(7,="" input);="" pinmode(led_builtin,="" output);="" pinmode(relaypin,="" digitalwrite(relaypin,="" low);="" digitalwrite(led_builtin,high);="" setup="" serial="" communication="" serial.begin(9600);="" while="" (!serial)="" {};="" serial.println(f("mqtt="" arduino="" demo"));="" serial.println();="" ethernet="" using="" dhcp="" if="" (ethernet.begin(mac)="=" 0)="" serial.println(f("unable="" to="" configure="" dhcp"));="" (;;);="" }="" serial.println(f("ethernet="" configured="" via="" serial.print("ip="" address:="" ");="" serial.println(ethernet.localip());="" (ethernet.localip()[0]);="" +="" ".";="" (ethernet.localip()[1]);="" (ethernet.localip()[2]);="" (ethernet.localip()[3]);="" serial.println(ip);="" mqtt="" mqttclient.setclient(ethclient);="" mqttclient.setserver(="" "192.168.1.103",="" 1883);="" configured"));="" mqttclient.setcallback(callback);="" dht.begin();="" serial.println(f("dht="" initialized"));="" serial.println(f("ready="" send="" data"));="" previousmillis="millis();" mqttclient.publish("home="" ip",="" ip.c_str());="" loop()="" frontdoorswitch="" garagedoor="" lichtstatus="analogRead(A0);//Reads" an="" ldr="" reads="" state="" it's="" time="" new="" data?="" (millis()="" -="" >="" publish_delay)="" senddata();="" mqttclient.loop();="" senddata()="" char="" msgbuffer[20];="" float="" h="dht.readHumidity();" 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");="" (mqttclient.connect(client_id))="" temp",="" dtostrf(t,="" 6,="" 2,="" msgbuffer));="" humid",="" dtostrf(h,="" deur",="" (statusbd="=" high)="" garage",="" (statusgd="=" "dicht");="" bel",="" (statuskd="=" l",="" dtostrf(lichtstatus,="" 4,="" 0,="" p",="" (pir="=" relay",="" (relaystate="=" mqttclient.subscribe("home="" relay");="" (startsend)="" callback(char*="" topic,="" byte*="" payload,="" unsigned="" length)="" serial.print("message="" arrived="" [");="" serial.print(topic);="" serial.print("]="" mqtt_broker="" (int="" <="" length;="" i++)="" serial.print((char)payload[i]);="" serial.println(payload[0]);="" (strncmp((const="" char*)payload,="" "on",="" 2)="=" digitalwrite(ledpin,="" high);="" "off",="" 3)="=" "read",="" 4)="="

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"="" northbound="" are="" going="" tomq="" the="" client,="" coming="" from="" client="" as="" available="" memory="" of="" a="" uno="" with="" ethernetcard="" is="" limited,="" i="" have="" kept="" topics="" short="" also,="" payloads="" nb="" temp="" temperature="" humid="" humidity="" deur="" door="" switch="" l="" lightintensity="" pr="" status="" pir="" sensor="" ip="" showing="" number="" relay="" relaystate="" there="" only="" one="" topic:="" sb="" payload="" here="" determines="" action:="" off="" -switch="" on-switch="" on="" read="" ask="" *="" #include="" "ethernet.h"="" "pubsubclient.h"="" "dht.h"="" #define="" client_id="" "hal"="" publish_delay="" 30000="" dhtpin="" 3="" dhttype="" dht11="" ledpin="" 13="" relaypin="" 8="" string="" ;="" bool="" statuskd="HIGH;" statusbd="HIGH;" statusgd="HIGH;" 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,="" pinmode(6,="" pinmode(7,="" input);="" pinmode(led_builtin,="" output);="" pinmode(relaypin,="" digitalwrite(relaypin,="" low);="" digitalwrite(led_builtin,high);="" setup="" serial="" communication="" serial.begin(9600);="" while="" (!serial)="" {};="" serial.println(f("mqtt="" arduino="" demo"));="" serial.println();="" ethernet="" using="" dhcp="" if="" (ethernet.begin(mac)="=" 0)="" serial.println(f("unable="" to="" configure="" dhcp"));="" (;;);="" }="" serial.println(f("ethernet="" configured="" via="" serial.print("ip="" address:="" ");="" serial.println(ethernet.localip());="" (ethernet.localip()[0]);="" +="" ".";="" (ethernet.localip()[1]);="" (ethernet.localip()[2]);="" (ethernet.localip()[3]);="" serial.println(ip);="" mqtt="" mqttclient.setclient(ethclient);="" mqttclient.setserver(="" "192.168.1.103",="" 1883);="" configured"));="" mqttclient.setcallback(callback);="" dht.begin();="" serial.println(f("dht="" initialized"));="" serial.println(f("ready="" send="" data"));="" previousmillis="millis();" mqttclient.publish("home="" ip",="" ip.c_str());="" loop()="" frontdoorswitch="" garagedoor="" lichtstatus="analogRead(A0);//Reads" an="" ldr="" reads="" state="" it's="" time="" new="" data?="" (millis()="" -="" >="" publish_delay)="" senddata();="" mqttclient.loop();="" senddata()="" char="" msgbuffer[20];="" float="" h="dht.readHumidity();" 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");="" (mqttclient.connect(client_id))="" temp",="" dtostrf(t,="" 6,="" 2,="" msgbuffer));="" humid",="" dtostrf(h,="" deur",="" (statusbd="=" high)="" garage",="" (statusgd="=" "dicht");="" bel",="" (statuskd="=" l",="" dtostrf(lichtstatus,="" 4,="" 0,="" p",="" (pir="=" relay",="" (relaystate="=" mqttclient.subscribe("home="" relay");="" (startsend)="" callback(char*="" topic,="" byte*="" payload,="" unsigned="" length)="" serial.print("message="" arrived="" [");="" serial.print(topic);="" serial.print("]="" mqtt_broker="" (int="" <="" length;="" i++)="" serial.print((char)payload[i]);="" serial.println(payload[0]);="" (strncmp((const="" char*)payload,="" "on",="" 2)="=" digitalwrite(ledpin,="" high);="" "off",="" 3)="=" "read",="" 4)="=" 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
Advertisement

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.

Solar powering an Attiny or Arduino with a capacitor, or just use AA? Part 2

Solar Charging a capacitor
Solar Charging a capacitor

As I had a 10.000uF (0.01F) capacitor and was awaiting my supercapacitors, I was wondering if I could perhaps use that, just to carry a circuit through the night.

With the aid of a 9 Volt Solarpanel (and a resistor) the 10.000uF capacitor was charged to 10Volts fairly quickly (it was a sunny day).

The charge in that can be calculated by 1/2*0.01*10² =0.5Ws. But as we can only use it at 5 Volt level in reality that is 0.125 Ws.
Also, as we take 1.8 Volt as our lower limit, we have to subtract 0.0126 Ws, leaving us with 0.109Ws.

With the earlier stated power consumption of 13.8uWatt that leaves us with about 7900 seconds or 2 hours and 12 minutes, which is obviously not enough to carry us through the night.
Yet, I wanted to test whether I was on the right track, so I used the following circuit to connect my circuit to the fully charged capacitor:
5volt

As it turned out, my circuit lasted for 1 hour and 25 minutes before it appeared to be dead, which i guess is close enough to the calculation, considering it was an old (>20 yrs) capacitor that might have suffered and maybe  had a bit of a leak current. Now before I get criticized that I am not taking into account that the capacitor is also discharged  during the day because it has to feed the circuit then as well… yes that is true, but I merely wanted to see if the capacitor could store enough load to begin with, to carry me through the night, which it cant. The charge -and thus the capacitor- would need to be at least  some 9 times bigger (so a 100.000uF minimally). I could have figured that all out just by calculation, but nothing beats a field test to see if calculations are right.

Anyway, while waiting for my supercapacitors to arrive (aliexpress) I had some time to think about what solarcell to use. The 9 Volt (5 Watt I seem to remember) seemed definite overkill, but from a few old gardenlamp I had some small solarpanels that delivered 2.5 Volt. I could put 3 of those in series (as they only give 2.5 Volt on a sunny day). I had no idea what Wattage they are but they are used to charge a 1.2V 40mAh NiCad, and some 300mAh NiCad. The latter seemed a better choice.
Ofcourse I could buy a solarpanel, but I first wanted to try with what I had available.

In part 1 I calculated a 1.5 Farad capacitor at 5 Volt is charged up to 19.5 Joule or 19.5 Wattseconds.
So if one wants to charge that capacitor with say a 5 Volt 1 Watt solarpanel one would need  a minimum of 19.5 secs to charge it (if we forget about a series resistor for a while).

IMG_20160505_172103Thriftstores sell these small solar Garden lights  usually for less than a euro. They have a small solarcell and inside a circuit build around an YX8018 IC that charges a single NiCad cell. Sometime sometimes a very small one (40mah)  sometimes a bigger one (800mAh). They need a full day of sun to charge and at dark an LED  lights up for a few hours. Now suppose the small solarpanels from my garden light are indeed enough to charge a 1.2 V 40mAh cell if left to charge for say 8 hrs.
The cells are  1.2 *40 mWh =48 mWh. If charged over 8 hrs that leaves a solar cell of 6mW. As the cells give 2.5 Volt in bright sun light, I would need 2 which then gives a total of 12mW (this is just theoretical, it is very low for a solarcell). So if I need a charge of 19.5W.s, that comes down to (19500/12=) 1625 secs or 27 minutes or 0.5 hrs to charge the 1.5 Farad capacitor. That is doable (if we  forget about the poweruse in the daytime).
In that 0.5 hrs obviously 13.8uW*0.5=6.2uWh is used just for the working of that circuit, which is small enough to ignore in terms of charge time. So, if a 1.5 Farad takes 0.5 hrs to charge, my 10.000uF should take 20/100 m or  12 secs. Lets see.
Now before I go on, just a word of warning: the calculations I do are partly limit calculations and do not always take all practical realities into account. For instance, a 5 Volt 12mW cell will be able to deliver 12/5=2.5mA. However if one tries to load an empty capacitor  with a series resistor of say 100 Ohm, then the max current that is requested is 50mA, obviously the photo cell cannot deliver that so the voltage drops and therefore the classical natural log curve of  charging a capacitor will not be followed. For any given moment the curve will follow the natural log curve for the  voltage at that moment, leading to a longer charge time.
Just a word: One could use the innards of the cheap garden light so, including the circuit around XY8018 IC to charge the caps, if one brings it up to 5 Volt. Various  circuits for that exist. I however decided to keep it simple and do a straight laod from  one or more  fotovoltaic cells.
Nevertheless, as halfway through my experimentations my Ultracaps arrived from Aliexpress (very fast delivery), it didnt seem much use to experiment with the 10.000uF any longer, so in Part 3 We go to the real work.
By the way, someone has already done some work on this.

 

Toggling a button in App Inventor

toggleApp Inventor is an easy piece of software  that starts you off in developing Android apps. If instead of two buttons to switch a state ON or OFF you want to have a button that toggles, the image shows how that is done.
Suppose I have a button called “bThuisToggle” it carries an image called “huis.png”. If I click it I want it to send a byte (85) and the next time I click it I want it to send another byte (117). I also want the image of the button to change into “huis_uit.png”.
The block in the picture shows clearly how to do that

Determine Number of Days into the year

For a project I needed to read data from EEPROM for every different day of the year. Using the day of the year from 1-365 as an index to read the memory seemed the easiest way. My RTClib library (from Adafruit) sadly didnt know a ‘day of the year’ function So I set out to make or find one. I came across a site where this was undertaken, but sadly that had a flaw that was probably not noticed by the owner because he only used it to determine if a day was even or odd. It gave me a good start though.
It entails altering the RTClib.h and RTClib.cpp files from the Adafruit RTC library.
First take the RTClib.h file and add the line as shown below:
rtclibh
Then open the RTClin.cpp file and add the function as shown below.
rtclibcppThis function cycles through an Array of ‘number of days per month’ stored in Flashram with PROGMEM. It starts by determining the current day and then add the days in the months from january till the current month to it.
Then it determines if february already passed and checks if it is a leapyear. If so it adds an extra day.
To use the function: define, initialize and start the RTC as usual. The call to “now.dayOfYear()” returns the number of days into the year.
e.g. Serial.print(now.dayOfYear();

The function is  m.m.somewhat  akin to the ‘days since 1-1-2000’ in the lib.

This function will work up to 2100 because that year is not a leap year (centuries as arule are not leap years). I could correct for that but then I also would have to correct for the year 2400 as that ís a leap year again (centuries are no leap years… unless the century is a multitude of 400).

Storing a float as a byte

I am using an NTC to read temperature. I use the Steinhart-Hart formula to calculate the temperature from the Resistance of the NTC. The output of that formula is a float (double integer, 4 bytes).
I also want to log the results in memory. For that I have a couple of choices
Store the floating point variable : that will cost me 32 bits of memory for every temperature value logged
Store the original NTC reading and just pull that through the Steinhart-Hart formula again when needed, that will cost me 16 bits for every temperature logged.
As I really don’t need the high decimal precision that a floating point value can give and as I really didn’t expect my temperature range to go outside -15 to +30 degrees Celcius, both 16 bits and 32 bits seemed serious overkill.

So I was wondering if I just couldn’t store it in in 1 Byte. As the Steinhart-Hart formula gives an approximation of the temperature, one can wonder how precise of a reading one needs, but I decided I wanted a solution of 0.25 degrees, though no doubt 0.5 degrees would have been enough already.
I figured I would use the MSB for the sign bit, that left 7 bits
decimal number 31 is equal to 0b00011111, so to cover my range I needed 5 bits for the temperature that left 2 bits
In those two bits I can store numbers 0-3, that I could use for the decimal fraction.
Extracting the essential bits from the binary level of the float seemed to much of a problem so I mainly worked with the decimal values.
In the function floatToByte I do a couple of essential things: I first check if it is a positive or a negative number as that determines the MSB I need to set in my byte. Then Itake the absolute value of the float so I get rid of o potential minus value, which would complicate calculations.
Then I turn the float into an integer and subtract that from the float. That leaves the decimal fraction. In order to keep at least some precision in that I have to put that in a double. Initially it was my idea to turn the values 0-9 into 0-3, but a simple division by 3 didnt have the desired effect as ‘9’ was sometimes 0.89 which by division would give a 2, So I decided on some simple ‘if’ conditions to convert the double fraction into half a nibble.
I then would shift the 5 bit temperature 2 bits to the right bitwise OR it with the fraction (on the two least significant bits and bitwise OR it with the sign bit.
That gave me temperature values that I can store in 1 Byte of EEPROM.

The way back – from memory byte to sensible temperature. Goes the other way around

byte floatToByte(float temp2) 
{
   byte sign = 128;
  if (temp2 >= 0) {
    sign = 0;
  }
  double temp = abs(temp2);
 
  int heel = int(temp);
  double fractie = temp - heel;
  
  fractie = (temp - heel);
  fractie = fractie * 100;
  byte fractie2 = 0;
  if (fractie >= 25) {
    fractie2 = 1;
  }
  if (fractie >= 50) {
    fractie2 = 2;
  }
  if (fractie >= 75) {
    fractie2 = 3;
  }
  byte temperatuur = (((heel << 2) | fractie2) | sign); 
  return temperatuur; 
  } 

void getTempByte(byte Temp) 
{ 
float temperatuurCelcius; 
if (Temp & 0b10000000) // check negative 
{
 Temp = Temp ^ 0b10000000; // knock out MSB byte 
 double fractie = (Temp & 0b00000011); 
 byte body = (Temp >> 2);
    Serial.println(-1 * (body + (fractie * 0.25)));
  }
  else
  {
    byte fractie = (Temp & 0b00000011);
    byte body = (Temp >> 2);
    Serial.println(body + fractie * 0.25);
  }


}
void setup() {
  Serial.begin(9600);
  byte x = floatToByte(+31.10);
  Serial.println(x, BIN);
  x = floatToByte(+31.25);
  Serial.println(x, BIN);
  x = floatToByte(31.50);
  Serial.println(x, BIN);
  x = floatToByte(+31.75);
  Serial.println(x, BIN);
  x = floatToByte(-31.75);
  Serial.println(x, BIN);
  x = floatToByte(+0.15);
  Serial.println(x, BIN);
  Serial.println("temperatuur ");
  getTempByte(0b1111101);

}
void loop() {
  // put your main code here, to run repeatedly:

}