IoT Sharing: Orange Pi

Hot

Showing posts with label Orange Pi. Show all posts
Showing posts with label Orange Pi. Show all posts

Wednesday, March 21, 2018

Demo 41: ESP32 connects with nRF24L01 2.4 GHz wireless chip

8:43 PM 19
1. Introduction
Figure: Module nRF24L01
The nRF24L01 2.4 GHz wireless chip from Nordic Semiconductor. It has:
- SPI interface, hardware link layer, multiple pipelines, ...
- The chip is very cheap.
Comparing to Wifi modules such as ESP8266, ESP32:
- It has less power consumption.
- It is cheaper (but need a MCU to control).
- It has lower data rate.
If your Wifi infrastructure is good, you can consider using Wifi modules for your application.
If power consumption is not your issue, you can consider using Wifi modules for your application.
If we use nrf24l01 and need to send data to cloud via Internet, consider using ESP or Raspberry as a Gateway.
Some main characteristics:
1.1 NRF24L01 Hardware Interface
- 8 pins Vcc, GND, IRQ, CE, SPI pins (CSN (chip select not), SCK, MISO, and MOSI).
- IO pins are 5V-tolerant and operating range of 1.9 to 3.6V for Vcc.
- CSN, SCK, MISO, and MOSI for data transmission and reception.
- The CSN pin is active-low, and is normally kept high. When this pin goes low, the 24L01 begins listening on its SPI port for data and processes it accordingly.
- CE is used to control data transmission and reception when in TX and RX modes.
- IRQ is the interrupt pin, and is active-low. There are three internal interrupts that can cause this pin to go low when they are active. Each of these bits can be masked out such that when the bit’s respective interrupt becomes active, the status of the IRQ pin is not changed.
1.2 Interfacing the nRF24L01 via SPI
- The SPI interface allows you to read/write registers, transmit data, receive data from and to the 24L01. For start step we use SPI at 2 Mbps. The high SPI data rates are used if you needed huge on-air data rates.
1.3 SPI Instruction Set Summary
- In order to send data to or receive data from the SPI port on the nRF24L01:
  + The CSN pin on the 24L01 must be high then bring the CSN pin low to receive SPI data. Note: this pin will stay low throughout the entire transaction.
  + You will transmit the command byte of the instruction you wish to send. If you are receiving data bytes for this instruction, you must then send one byte to the 24L01 for every one byte that you wish to get out of the 24L01. If you are just sending the 24L01 data, you simply send your data bytes and generally don’t worry about what it sends back to you.
  + Once you have transmitted and/or read all of the bytes that you need, you bring CSN back high.
  + When you send any command byte, the 24L01 always returns to you the STATUS register.
1.4 FIFO Info
- There are FIFOs for both TX and RX modes.
- Both of the FIFOs  will hold the three newest packets that have been put into them. If you receive three packets in RX mode and you don’t read the payloads, the first (oldest) packet received is pushed out by the newest packet received. The same goes for the TX payload – if you load three packets and don’t transmit them (by executing the aforementioned CE toggle), then the fourth packet will push out the first packet you loaded.
1.5 Data Packet Format
- The transceiver protocol has 2 modes: Shockburst and Enhanced Shockburst
- The message format for both Shockburst and Enhanced Shockburst modes are different.
- In both modes, the preamble is sent first (1 byte), is used to allow the receiver to know that what it is hearing is the beginning of a packet and not just on-air noise.
- The next bytes sent are the address bytes. This is set by the user, and is between three and five bytes long.
- The next bytes sent is different between the two modes. In Enhanced Shockburst only, a flag word of nine bits is sent to indicate the message status concerning re-transmissions. Only two bits are currently used (a count of resent packets), and the other seven are reserved for future use.
- The last half of the packet that is sent is the same in both modes. The first of the fields to be sent in both modes is the payload data. The length of the payload is also set by the user (1 to 32 bytes long). The final part of the packet to be sent is the CRC, which is user-settable (0, 1, or 2 byte(s)).
Let 's make 2 demos:
- Demo 1: ESP32 Nano will send "hello" message to Arduino.
- Demo 2: Arduino Nano will send "hello" message to ESP32.
If you have 2 ESP32 you can replace Arduino Nano with ESP32.
2. Hardware
You need 2 Arduino/ESP8266/ESP32/Raspberry boards for testing: 1 board will send/receive message and 1 board will receive/send message which was sent by first board.
I used Arduino for testing, just do wiring like below:
Arduino_D8      x   NRF24_CSN
Arduino_D7      x   NRF24_CE
Arduino_D13    x   NRF24_SCK
Arduino_D11    x   NRF24_MOSI
Arduino_D12    x   NRF24_MISO

Arduino_3.3      x   NRF24_Vcc
Arduino_GND  x   NRF24_GND
For ESP32, I modified the library RF24 so that the software can use SPI software instead of using SPI hardware. Do wiring like below:
NRF24_CE      x   ESP32_IO12
NRF24_CSN    x   ESP32_IO14
NRF24_SCK    x   ESP32_IO26
NRF24_MISO  x   ESP32_IO25
NRF24_MOSI  x   ESP32_IO27
NRF24_Vcc      x   ESP32_3.3V
NRF24_GND    x   ESP32_GND  
3. Software
For ESP32, I modified the library RF24 (https://github.com/nhatuan84/RF24) so that the software can use SPI software insted of using SPI hardware. The new API has new form:
RF24(uint16_t _cepin, uint16_t _cspin, uint16_t sck, uint16_t miso, uint16_t mosi)
and to create an instance: RF24 radio(12, 14, 26, 25, 27);
For Arduino, we use SPI hardware so just use form:  
RF24(uint16_t _cepin, uint16_t _cspin)
and the instance is RF24 radio(7,8);
- Demo 1: ESP32 Nano will send "hello" message to Arduino.
ESP32 transmitter code
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
#include  <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"
char msg[6] = "hello";
RF24 radio(12, 14, 26, 25, 27);
const uint64_t pipe = 0xE8E8F0F0E1LL;

void setup(void) {
  Serial.begin(115200);
  radio.begin();
  radio.setChannel(2);
  radio.setPayloadSize(7);
  radio.setDataRate(RF24_250KBPS);
  radio.openWritingPipe(pipe);
}
void loop(void) {
  Serial.println("send ...");
  radio.write(msg, 6);
  delay(3000);
}
Arduino receiver code
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"
char msg[6];
RF24 radio(7,8);
const uint64_t pipe = 0xE8E8F0F0E1LL;
void setup(void){
 Serial.begin(115200);
 radio.begin();
 radio.setChannel(2);
 radio.setPayloadSize(7);
 radio.setDataRate(RF24_250KBPS);
 radio.openReadingPipe(1,pipe);
 radio.startListening();
}

void loop(void){
 if (radio.available()){  
     radio.read(msg, 6);      
     Serial.println(msg);
     delay(10);
 }
 else{
  //Serial.println("No radio available");
 }
}
- Demo 2: Arduino Nano will send "hello" message to ESP32.
ESP32 receiver code
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"
char msg[6];
RF24 radio(12, 14, 26, 25, 27);
const uint64_t pipe = 0xE8E8F0F0E1LL;
void setup(void){
 Serial.begin(115200);
 radio.begin();
 radio.setChannel(2);
 radio.setPayloadSize(7);
 radio.setDataRate(RF24_250KBPS);
 radio.openReadingPipe(1,pipe);
 radio.startListening();
}

void loop(void){
 if (radio.available()){  
     radio.read(msg, 6);      
     Serial.println(msg);
     delay(10);
 }
 else{
  //Serial.println("No radio available");
 }
}
Arduino transmitter code

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
#include  <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"
char msg[6] = "hello";
RF24 radio(7,8);
const uint64_t pipe = 0xE8E8F0F0E1LL;

void setup(void) {
  Serial.begin(115200);
  radio.begin();
  radio.setChannel(2);
  radio.setPayloadSize(7);
  radio.setDataRate(RF24_250KBPS);
  radio.openWritingPipe(pipe);
}
void loop(void) {
  Serial.println("send ...");
  radio.write(msg, 6);
  delay(3000);
}
4. Result
Figure: ESP32 received "hello" message from Arduino
Read More

Monday, January 22, 2018

Demo 40: Create a Facebook Messenger chat bot for monitoring and controlling home devices using Raspberry/Orange Pi and ESP32/8266

12:05 AM 1
1. Introduction
In this demo, I will show you how to create a Facebook Messenger chat bot for monitoring and controlling home devices using Raspberry/Orange Pi and ESP32/8266. This is not a full solution so you need to improve it by yourself.
Figure: Facebook Messenger chat bot for monitoring and controlling home devices
There are 2 steps to make this demo:
- How to setup a Facebook chat bot
- How to setup local system (Raspberry/Orange Pi, ESP32/8266)
This is the model of the demo:
Figure: The model of the demo
2. Setup
2.1 Create Facebook page
You can refer to this guideline. And choose type of Page is Business, Brand or Place. In my demo, I created a page named IoT Sharing.
2.2 Setup Facebook chat bot
In order to develop or use Facebook services for Software development you need to register a Facebook developer account here.
After created a FB developer account choose My Apps -> Add a new App -> Fill Display name
In Select a Product -> choose messenger -> Set Up
Choose Webhooks -> Setup Webhooks
Note: We do not do this step now. This step will be done after running the Raspbbery/Orange Pi software. Because after filled Callback URL, Verify Token and press Verify and Save, FB will send a GET request with "hub.challenge=value of Verify Token" (in this case Verify Token is "iotsharing.com" string) to Pi. Pi need to check the value of hub.challenge must match the value that we filled in Verify Token field (in this case Verify Token is "iotsharing.com" string). And then send this hub.challenge back to FB to finish the verification.
1
2
3
4
5
6
@app.route('/', methods=['GET'])
def handle_verification():
 if(request.args['hub.challenge'] == 'iotsharing.com'):
  return request.args['hub.challenge']
 else:
  return 'not match'
Fill information like below and choose Verify and Save.
choose the Page that you created in previous step and Subscribe/Unsubscribe.
Finally, extract the ACCESS_TOKEN of the FB app so that our application can authenticate to use FB services.
It is done for Facebook setup step.
2.2 Setup local system (Raspberry/Orange Pi, ESP32/8266)
In this demo, Pi will keep some roles:
- Communicate with Facebook server to receive and respond message.
- Parse Facebook message and then using MQTT protocol to publish the commands to ESP32/8266 clients and subscribe responses from ESP32/8266 clients.
- Refer to this post to setup MQTT for Pi.
- We use Python Paho MQTT for local communication. Refer to this post to install it.
- Besides we need to install some packages (Flask, ngrok) on Raspberry/Orange Pi for our demo. 
+ Flask is a Python web framework. In our demo, It is a web server to handle Facebook https request.
+ ngrok secure introspect-able tunnels to local host web hook development tool and debugging tool. This tool helps Facebook server can see our Flask local web server.
From Pi Terminal running the commands:
+ Install Flask Python server: "sudo pip install Flask"
+ Download ngrok: "wget https://bin.equinox.io/a/26q6mq7ddJR/ngrok-2.2.9-linux-arm.zip"
+ Unzip zip file for executable app: "unzip ngrok-2.2.9-linux-arm.zip"
3. Hardware
- 1 ESP32 or ESP8266
- 1 Raspberry Pi or Orange Pi
- 1 LED connect to ESP
- 1 temperature sensor connect to ESP. 
In this demo I do not use temperature sensor. I used random(min, max) function to generate temperature.
4. Software
The source code of this demo can be found on github.
Define messages:
- Pi send MQTT request topics to ESP:
Temperature topic: "floor1/room1/temp1" to measure temperature
Led topic:               "floor1/room1/led1" to set "0" (off) or "1" (on)
- ESP send MQTT response topics to Pi:
Temperature response topic: "floor1/room1/temp1/res" with temperature value
Led response topic:               "floor1/room1/led1/res" to inform that the request was executed
- The template for Facebook message:
"set floor1/room1/led1 on" -> turn on LED and get response
"set floor1/room1/led1 off" -> turn off LED and get response
"get floor1/room1/temp1" -> request temperature measurement and get response
ESP code I reused the post (esp32chatbot.ino)
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
#include <WiFi.h>
#include <PubSubClient.h>

const char* ssid = "dd-wrt";
const char* password = "0000000000";
//ip address of Raspberry/orange pi
const char* mqtt_server = "192.168.1.106";
char msg[20];

/* create an instance of PubSubClient client */
WiFiClient espClient;
PubSubClient client(espClient);

/*LED GPIO pin*/
const char led = 4;
/* topics */
#define TEMP_TOPIC    "floor1/room1/temp1"
#define LED_TOPIC     "floor1/room1/led1" /* on, off */

void receivedCallback(char* topic, byte* payload, unsigned int length) {
    Serial.print("topic: ");
    Serial.println(topic);
      if(strcmp(topic, LED_TOPIC) == 0){
        Serial.print("payload: ");
        for (int i = 0; i < length; i++) {
          Serial.print((char)payload[i]);
        }
        Serial.println();
        /* we got '1' -> on */
        if ((char)payload[0] == '1') {
          digitalWrite(led, HIGH); 
          snprintf (msg, 20, "%s", "on");
        /* publish the response */
        client.publish(LED_TOPIC "/res", msg);
        } else {
          /* we got '0' -> on */
          digitalWrite(led, LOW);
          snprintf (msg, 20, "%s", "off");
          client.publish(LED_TOPIC "/res", msg);
        }
    }else {
        snprintf (msg, 20, "%d", random(0, 40));
        client.publish(TEMP_TOPIC "/res", msg);
    }
}

void mqttconnect() {
  /* Loop until reconnected */
  while (!client.connected()) {
    Serial.print("MQTT connecting ...");
    /* client ID */
    String clientId = "ESP32Client";
    /* connect now */
    if (client.connect(clientId.c_str())) {
      Serial.println("connected");
      /* subscribe topic */
      client.subscribe(LED_TOPIC);
      client.subscribe(TEMP_TOPIC);
    } else {
      Serial.print("failed, status code =");
      Serial.print(client.state());
      Serial.println("try again in 5 seconds");
      /* Wait 5 seconds before retrying */
      delay(5000);
    }
  }
}

void setup() {
  Serial.begin(115200);
  // We start by connecting to a WiFi network
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  /* set led as output to control led on-off */
  pinMode(led, OUTPUT);

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());

  /* configure the MQTT server with IPaddress and port */
  client.setServer(mqtt_server, 1883);
  /* this receivedCallback function will be invoked 
  when client received subscribed topic */
  client.setCallback(receivedCallback);
}
void loop() {
  /* if client was disconnected then try to reconnect again */
  if (!client.connected()) {
    mqttconnect();
  }
  /* this function will listen for incomming 
  subscribed topic-process-invoke receivedCallback */
  client.loop();
}
Pi code (chatbot.py):
We use variable history to hold the id of Facebook messenger sender while waiting for the response from ESP. This sender id is used in reply() function to send response back to Facebook messenger sender.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
from flask import Flask, request
import requests
import paho.mqtt.publish as publish
import paho.mqtt.client as mqtt
import thread

ACCESS_TOKEN = "your_fb_access token_here";

#hold sender id
history = dict()

set_cmd = 'floor1/room1/led1'
get_cmd = 'floor1/room1/temp1'

#respond to FB messenger
def reply(user_id, msg):
    data = {
        "recipient": {"id": user_id},
        "message": {"text": msg}
    }
    resp = requests.post("https://graph.facebook.com/v2.6/me/messages?access_token=" + ACCESS_TOKEN, json=data)
    print(resp.content)

#MQTT handler
def on_connect(mqttc, obj, flags, rc):
    print("rc: "+str(rc))
def on_message(mqttc, obj, msg):
    print(msg.topic+": "+str(msg.payload))
    if msg.topic in history:
        user_id = history[msg.topic]
  #reply FB messenger
        reply(user_id, msg.payload)
        history.pop(msg.topic, None)

mqttc = mqtt.Client()
mqttc.on_connect = on_connect
mqttc.on_message = on_message
mqttc.connect("localhost", 1883, 60)
mqttc.subscribe("floor1/#", 0)

#MQTT subscribe thread 
def mqtt_thread( threadName, delay):
   mqttc.loop_forever()
try:
   thread.start_new_thread( mqtt_thread, ("mqtt-thread", 0, ) )
except:
   print "Error: unable to start thread"

#Flask web server instance
app = Flask(__name__)

#handle GET request from Facebook
@app.route('/', methods=['GET'])
def handle_verification():
 if(request.args['hub.challenge'] == 'iotsharing.com'):
  return request.args['hub.challenge']
 else:
  return 'not matched'

#handle POST request from Facebook
@app.route('/', methods=['POST'])
def handle_incoming_messages():
    data = request.json
    print(data)
    sender = data['entry'][0]['messaging'][0]['sender']['id']
    message = data['entry'][0]['messaging'][0]['message']['text']
    print(message)
    if(message.startswith('set')):
        arr = message.split()
        l = len(arr)
        if(l == 3 and set_cmd == arr[1]):
            cmd = arr[1]
            val = '1' if arr[2]=='on' else '0'
            publish.single(cmd, val, hostname="localhost")
   #record command with sender id
            history[cmd+'/res'] = sender
            return 'ok'
    elif(message.startswith('get')):
        arr = message.split()
        l = len(arr)
        if(l == 2 and get_cmd == arr[1]):
            cmd = arr[1]
            publish.single(cmd, '', hostname="localhost")
   #record command with sender id
            history[cmd+'/res'] = sender
            return 'ok'
    reply(sender, 'invalid query')
    return "ok"

if __name__ == '__main__':
app.run(debug=True)
5. Steps to deploy
- MQTT broker run on Pi
- Open 2 Terminal on Pi:
   + Run "python chatbot.py" with Flask in it.
   + Run ngrok (5000 is the port Flask listen on): "./ngrok http 5000"

Copy the url in red box to Callback URL field that mention in step 2.2 Setup Facebook chat bot
Note: in case we shutdown ngrok and run it again the new url will be generated. We have to re-register this url to Facebook.
Choose Webhooks -> Edit Subscription
And then Unsubcribe and Subscribe the page again:
Now go to the Page that we created, choose About and Send Message
And type one of commands:
"set floor1/room1/led1 on"
"set floor1/room1/led1 off"
"get floor1/room1/temp1"

6. Result



Read More

Saturday, August 26, 2017

Demo 30: How to use Arduino ESP32 MQTTS with MQTTS Mosquitto broker (TLS/SSL)

9:05 PM 16
1. Introduction
Arduino-ESP32 SDK has been updated and new WiFiClientSecure library not working any more. In order to fix it, please using the old github commit or download the zip file here.
After downloading the old commit; extract it; go to the libraries folder; copy the
WiFiClientSecure folder; replace the current WiFiClientSecure folder (in Arduino/hardware/espressif/esp32/libraries or refer here) by the copied WiFiClientSecure folder.
- In this tutorial, I will show you how to use ESP32 MQTTS with MQTTS Mosquitto broker (TLS/SSL).
- In order to make this tutorial, please refer topics:
How to set up secure transportation for MQTT Mosquitto broker with SSL/TLS
Demo 29: How to use HTTPS in Arduino ESP32
Demo 14: How to use MQTT and Arduino ESP32 to build a simple Smart home system
- The requirement for this demo: ESP32 with a LED on it will turn On/Off when subscribing a topic "smarthome/room1/led" with values (0: off, 1: on).
2. Steps
- After doing the steps in this demo How to set up secure transportation for MQTT Mosquitto broker with SSL/TLS, you have to extract the content of ca.crt for SSL/TLS handshake phase by running the command:  
cat /etc/mosquitto/certs/ca.crt
 Figure: Extract content of ca.crt
- Get the IP address of machine that run MQTT mosquitto by running command: ifconfig or if you use MDNS for that machine you can follow this tutorial to get the IP directly from ESP32: How to get the IP address of a node by its mdns host name in Arduino ESP32.
- We will use WiFiClientSecure class for SSL/TLS handshake phase and PubSubClient library for ESP32 MQTT communication. Please see the topics that I mentioned above.
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <PubSubClient.h>
#include <ESPmDNS.h>

/* change it with your ssid-password */
const char* ssid = "dd-wrt";
const char* password = "0000000000";
/* this is the MDNS name of PC where you installed MQTT Server */
const char* serverHostname = "iotsharing";

const char* ca_cert = \ 
"-----BEGIN CERTIFICATE-----\n" \
"MIIDpzCCAo+gAwIBAgIJAOHc50EeJ6aeMA0GCSqGSIb3DQEBDQUAMGoxFzAVBgNV\n" \
"BAMMDkFuIE1RVFQgYnJva2VyMRYwFAYDVQQKDA1Pd25UcmFja3Mub3JnMRQwEgYD\n" \
"VQQLDAtnZW5lcmF0ZS1DQTEhMB8GCSqGSIb3DQEJARYSbm9ib2R5QGV4YW1wbGUu\n" \
"bmV0MB4XDTE3MDgyNzAyMDQwNFoXDTMyMDgyMzAyMDQwNFowajEXMBUGA1UEAwwO\n" \
"QW4gTVFUVCBicm9rZXIxFjAUBgNVBAoMDU93blRyYWNrcy5vcmcxFDASBgNVBAsM\n" \
"C2dlbmVyYXRlLUNBMSEwHwYJKoZIhvcNAQkBFhJub2JvZHlAZXhhbXBsZS5uZXQw\n" \
"ggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC8mQfR058k7LBV7Xt6RiZL\n" \
"BIpC5ewSweAnsaS6Ue+jx6uruJsccnIJbiHJVjOcSYV3JLMt3un7d0JTottW6Zx/\n" \
"VleYC4CUzf3bcHLe7Qhl0veP9QAdZceblMCbEqAM9227EaXKQVzAYGwRnuxvfJM7\n" \
"P84iu2J/zB4o+AEWUJDIW38SO4b+0i1FYHmKKxEx7dztDyCJvTsn35wX3oKlJ5e+\n" \
"na/6csD+Ngh9QQ+wDd02TBqXKB7UXyRT5ECesu19U6CTE7Wr9xECbDO262aD6GtC\n" \
"HpeSAWqa6HKbKjZ20pL5V5ceS85TdWbvPdVrFUDWMIhK9dNuwhIK0s6VyRcJkbe5\n" \
"AgMBAAGjUDBOMB0GA1UdDgQWBBQPZ0u1jIg65jT3Th42VGMnya6VDDAfBgNVHSME\n" \
"GDAWgBQPZ0u1jIg65jT3Th42VGMnya6VDDAMBgNVHRMEBTADAQH/MA0GCSqGSIb3\n" \
"DQEBDQUAA4IBAQB8JrNsV32aXBOLSX8WqoHuU2NOJH+1fTdGDLYLEAPe/x3YxkNC\n" \
"MJDx8TGLSQsz4L0kCsLEQ/qsnkuPJUt3x7eNIMOrvS+zDv9wXqnGwMgeAOtEkG5n\n" \
"NbPezM50ovgZAuEZMphp2s/Zl0EROydnqpkweWa5bxYRkiQBlp0nUkCtec3PZ6iO\n" \
"QVPj/bHHi4T3jkbL0+oLNShv9Zw9hr6BkKCVqeHe9prlOMVuEJOVrEKzkhhAY90p\n" \
"Wwrj+OQYCLllJVD9VQhLVOXLg1bSuqkld3PCQBFNvrvk4Up61wuu/Oj5c5g8vwYd\n" \
"0ul29sU3heTw4ZXifpbMXRM36LFNH5uLrSba\n" \
"-----END CERTIFICATE-----\n";

/* create an instance of WiFiClientSecure */
WiFiClientSecure espClient;
PubSubClient client(espClient);

/*LED GPIO pin*/
const char led = 4;

/* topics */
#define COUNTER_TOPIC    "smarthome/room1/counter"
#define LED_TOPIC     "smarthome/room1/led" /* 1=on, 0=off */

long lastMsg = 0;
char msg[20];
int counter = 0;

void receivedCallback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Message received: ");
  Serial.println(topic);

  Serial.print("payload: ");
  for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);
  }
  Serial.println();
  /* we got '1' -> on */
  if ((char)payload[0] == '1') {
    digitalWrite(led, HIGH); 
  } else {
    /* we got '0' -> on */
    digitalWrite(led, LOW);
  }

}

void mqttconnect() {
  /* Loop until reconnected */
  while (!client.connected()) {
    Serial.print("MQTT connecting ...");
    /* client ID */
    String clientId = "ESP32Client";
    /* connect now */
    if (client.connect(clientId.c_str())) {
      Serial.println("connected");
      /* subscribe topic */
      client.subscribe(LED_TOPIC);
    } else {
      Serial.print("failed, status code =");
      Serial.print(client.state());
      Serial.println("try again in 5 seconds");
      /* Wait 5 seconds before retrying */
      delay(5000);
    }
  }
}

void setup() {
  Serial.begin(115200);
  // We start by connecting to a WiFi network
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  /* set led as output to control led on-off */
  pinMode(led, OUTPUT);

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
  /*setup MDNS for ESP32 */
  if (!MDNS.begin("esp32")) {
      Serial.println("Error setting up MDNS responder!");
      while(1) {
          delay(1000);
      }
  }
  /* get the IP address of server by MDNS name */
  Serial.println("mDNS responder started");
  IPAddress serverIp = MDNS.queryHost(serverHostname);
  Serial.print("IP address of server: ");
  Serial.println(serverIp.toString());
  /* set SSL/TLS certificate */
  espClient.setCACert(ca_cert);
  /* configure the MQTT server with IPaddress and port */
  client.setServer(serverIp, 8883);
  /* this receivedCallback function will be invoked 
  when client received subscribed topic */
  client.setCallback(receivedCallback);
  
}
void loop() {
  /* if client was disconnected then try to reconnect again */
  if (!client.connected()) {
    mqttconnect();
  }
  /* this function will listen for incomming 
  subscribed topic-process-invoke receivedCallback */
  client.loop();
  /* we increase counter every 3 secs
  we count until 3 secs reached to avoid blocking program if using delay()*/
  long now = millis();
  if (now - lastMsg > 3000) {
    lastMsg = now;
    if (counter < 100) {
      counter++;
      snprintf (msg, 20, "%d", counter);
      /* publish the message */
      client.publish(COUNTER_TOPIC, msg);
    }else {
      counter = 0;  
    }
  }
}
3. Result
Read More

How to set up secure transportation for MQTT Mosquitto broker with SSL/TLS

7:19 PM 3
1. Introduction
In Demo 29 you knew how SSL/TLS is important to make communication between client and server safer. So I will show you how to set up secure transportation for MQTT Mosquitto broker with SSL/TLS.
2. Steps
Note: This way is applied for Linux OS
2.1. Generating the server self-certificates
- Download the script: https://github.com/owntracks/tools/blob/master/TLS/generate-CA.sh
- Set execution permission: chmod +x generate-CA.sh
- Run the script: ./generate-CA.sh
- You will see created files:
Figure: Created files when running the script
- Run commands:  
     sudo cp ca.crt /etc/mosquitto/certs
     sudo cp tuan-ThinkPad-T410.* /etc/mosquitto/certs
2.2. Mosquitto configuration
- Run command:
     sudo gedit /etc/mosquitto/mosquitto.conf
- And paste lines to it:
     # Plain MQTT protocol
     listener 1883
     # End of plain MQTT configuration
     # MQTT over TLS/SSL
     listener 8883
     cafile /etc/mosquitto/certs/ca.crt
     certfile /etc/mosquitto/certs/tuan-ThinkPad-T410.crt
     keyfile /etc/mosquitto/certs/tuan-ThinkPad-T410.key

- Restart mosquitto server:
     sudo service mosquitto restart
2.3. Testing MQTT TLS/SSL configuration
- Run commands:
     mosquitto_sub -t \# -v --cafile /etc/mosquitto/certs/ca.crt -p 8883
     mosquitto_pub --cafile /etc/mosquitto/certs/ca.crt -h localhost -t "smarthome/room1/led" -m 0 -p 8883


 Figure: Testing result
 

Read More

Thursday, June 1, 2017

How to turn the Orange Pi/Raspberry Pi into an IoT node

3:53 AM 0
1. Introduction
- From the Orange Pi hardware specification, we can build it as a: small computer, a mini server, a gateway, a media center, ... I suggest that we should not connect it directly to sensors or control actuators that need the high accuracy (but low accuracy is fine), because the current Linux based OS in it have to run many applications and services in background/foreground, so there is a delay time when reading the sensors or controlling actuators and it make the result is not accurate. But if you still want to use Linux because of rich features, you can consider to install a Real Time Linux for it.
- In order to turn the Orange Pi into an IoT node, there are some applications and services that need to be equipped:
+ mDNS: the benefits of mDNS you can refer here: Demo 9: How to use mDNS to resolve host names to Arduino ESP32 IP addresses
+ mosquitto MQTT broker, you can refer Demo 14: How to use MQTT and Arduino ESP32 to build a simple Smart home system
+ apache2 a HTTPD - Apache2 Web Server (there are others options like nginx, nodejs)
+ PHP a scripting language for making dynamic web pages.
+ sqlite3 a small, self-contained, high-reliability database (data in stored in a local file).
2. Installation 
Note: these steps below can be applied for Raspberry Pi by replacing orangepi by raspberrypi
2.1 Install mDNS
- Step 1: from command line typing: "sudo apt-get install avahi-daemon" to installl avahi
- Step 2: edit the file "sudo nano /etc/avahi/avahi-daemon.conf"
with:
[server]
host-name=orangepi
domain-name=local

With this configuration, the host name "orangepi.local" will be used to resolve IP address.
- Step 3: restart "avahi-daemon" service by command:
"service avahi-daemon restart"
- Step 4: After finishing, you can test it by command:
"ping orangepi.local" 
Now we can change the way to ssh: "ssh root@orangepi.local"
2.2 Install mosquitto
- From command line typing:
"sudo apt-get install mosquitto mosquitto-clients"
- From another machine which installed mosquitto, open 2 Terminals and type 2 commands in each Terminal:
Terminal 1: type "mosquitto_sub -v -h orangepi.local -p 1883 -t '#'"
Terminal 2: type "mosquitto_pub -h orangepi.local -t 'room1/temp' -m 30
You will see:
Figure: Install mosquitto successfully
2.3 Install apache2
 - From command line typing:
"sudo apt-get update" 
and then 
"sudo apt-get install apache2"
- After finishing installation, from web browser type "http://orangepi.local/", you will see the page
Figure: Install apache2 successfully
 2.4 Install PHP
- From command line typing:
"apt-get install php libapache2-mod-php -y"
-  After finishing installation, from command line typing:
"sudo mkdir /var/www/html/phphello"
"sudo nano /var/www/html/phphello/hello.php"
copy and paste content: Hello World
'; ?>
then Ctrl + O and Ctrl + X
- From web browser go: "http://orangepi.local/phphello/hello.php"

Figure: Install PHP successfully

2.5 Install sqlite3
- From commad line typing:
"sudo apt-get install sqlite3 libsqlite3-dev"
- After finishing installation, from command line type: "sqlite3" and see
Figure: Install sqlite3 successfully
Done!!!
Read More

Sunday, May 28, 2017

How to install and setup Serial - WiFi for Orange PI

4:16 AM 1
1. Introduction
- The price of Orange Pi is cheap, but the hardware is fine. It would be a good option for your project where price is considered. You can refer here.
- In this tutorial I will show steps to setup Armbian OS for Orange Pi Lite. You can refer this tutorial for the other models.
- Armbian OS have 2 versions: Command line (no GUI) and Desktop (GUI).
- This tutorial has 3 steps:
Step 1: Format memory sdcard and Write image to memory sdcard
Step 2: Setup Serial for Orange Pi
Step 3: Setup WiFi for Orange Pi 
- Hardware:
  + 1 microSD reader
  + 1 memory sdcard
  + Orange Pi Lite with 5V 2A power adapter
  + 1 USB-TTL and 3 Female-Female jumper to connect pins RX, TX, GND between USB-TTL and Orange Pi Lite
Step 1
- Download Armbian.img here
  Figure: choose Orange Pi in list of Armbian supported boards
Figure: I choose Orange Pi Lite with command line version

For Windows users:
+ Write image to memory sdcard using Win32 Disk Imager (https://sourceforge.net/projects/win32diskimager)

Figure: Win32 Disk Image write image to microSD
For Linux users:
+ List all hard disks using "sudo fdisk -l" and look for Disk that is your microSD. In my case it is "Disk /dev/sdb"
+ Format using command "sudo mkfs.vfat -I /dev/sdb" or Right click mouse on the disk and choose Format.

+ Write image to microSD using:
"sudo dd bs=1024 if=Armbian.img of=/dev/sdb"
- After finishing writting, plug the microSD to Orange Pi

Step 2: Setup Serial for Orange Pi

Figure: Serial pins on Orange Pi Lite
 Figure: USB-TTL
Connect:
[Pi GND - USB TTL GND] 
[Pi TX - USB TTL RX]  
[Pi RX - USB TTL TX] 
 Figure: Orange Pi - USB TTL
Using Putty Serial to create connection with Orange Pi
You can download it here:
Ubuntu: using command "sudo apt-get install putty"
Debian: using command "sudo aptitude install putty"
Figure: Configure Putty Serial with Speed 115200
Figure: Serial screen
Note: first time login, OS will request us to change default password(1234) of root user, just follow it.
Step 3: Setup WiFi for Orange Pi
- Run command "nmcli radio wifi on" to turn on WiFi.
- Run command below to connect to WiFi
"nmcli d wifi connect your_WiFiSSID password your_WiFiPassword
Now you do not need USB TTL any more. We can use SSH to connect to Orange Pi using Putty or command line "ssh root@192.168.1.104" to login as root
Figure: You can search a mobile application called "Fing" (on Google Play or Apple Store) to scan the IP address of Orange Pi
Read More
Thường mất vài phút để quảng cáo xuất hiện trên trang nhưng thỉnh thoảng, việc này có thể mất đến 1 giờ. Hãy xem hướng dẫn triển khai mã của chúng tôi để biết thêm chi tiết. Ðã xong