Saturday, September 23, 2017

Chalieplexing 2

This is the seond tutorial on Charlieplexing.
In the first story, which you can find by clicking here, I told you why Charlieplexing is such a wonderfull technique and how to do the wiring.

This chapter is going to delve deeper into the software.

So let us first look again at the wiring. Here is the setup for using 5 pins to adress 20 leds.



I am using an Attiny85 here because an Arduino would be overkill. You can however substitute the Attiny85 with an Arduino as the code stays the same. Only thing you will have to do is to substitute the right pinnumbers in the program.

The previous story told you how to adress a single led. Lets resume that here.

We start with putting all pins of the Arduino (or Tiny) in 3-state mode to make sure no leds are on:

int led1 = 0; // pen PWM0
int led2 = 1; // pen PWM1
int led3 = 2; // pen ADC1
int led4 = 3; // pen ADC3
int led5 = 4; // pen ADC2
pinMode(led1, INPUT)
pinMode(led2, INPUT);
pinMode(led3, INPUT);pinMode(led4, INPUT);
pinMode(led5, INPUT);


Now to put on led number 13 you adress it as follows:

pinMode (led2, OUTPUT);
digitalWrite (led2, HIGH);
pinMode (led5, OUTPUT);
digitalWrite (led5, LOW);


This way we can adress all leds individually. However it takes a lot of coding (as you saw in the previous story) and that is prone to errors. So we need to find an easier way.

Best thing to do is to put all led wiring in an array. Then we just need to access the array index to have all data present. Sounds more difficult as it is.

Lets start with defining an array with 20 entries, one for each led, and 2 elements per entry for each pin per led. So the array would look like this:

const int ledpins[20][2] ={
  // this array contains the pins per led
  // edit the pin numbers to your own wiring
  {1,0},
  {0,1},
  {2,0},
  {0,2},
  {3,0},
  {0,3},
  {4,0},
  {0,4},
  {2,1},
  {1,2},
  {3,1},
  {1,3} ,
  {4,1},
  {1,4},
  {3,2},
  {2,3},
  {4,2},
  {2,4},
  {4,3},
  {3,4}
};


So how does this work. Lets start easy. Led number 1 is attached to pins 1 and 0 just like it is punt in the array:

{1,0}. Led number two is wired the other way round and you can find that in the array to: {0,1}. Well let us now look at led number 12. In the wiring schematic you can see it is attached to Arduino pin number 1 and pin number 3. And that is exactly what you will find in the array entrance number 12 being {1,3}.
Lets take another example. Led number 17 is attached to pins 4 and 2 just like array entrance number 17 describes

{4,2}

That is easy isn't it. The array just describes how the pins are wired.

In your code always start with putting all leds off:

void alloff()
// this puts all leds off
{
  for(int i = 0; i < 5; i++)
  {
    pinMode (pins[i], INPUT);
  }
}


That is easy. Just like in the previous story. We set all pins in the INPUT mode so they are in tri-state which turns all leds off.

Next step is to make a function that turns a certain led ON.

void ledon(int lednr)
// choose a led from the array on put it ON
{

  pinMode (ledpins[lednr][0], OUTPUT);
  digitalWrite (ledpins[lednr][0], HIGH);

  pinMode (ledpins[lednr][1], OUTPUT);
  digitalWrite (ledpins[lednr][1], LOW);
  delay(slowdown2);

}


That's all that is to it.

Now if you want to put LED 13 ON for a certain amount of time (determined by the variable slowdown2)you just have to use the next code:

ledon(13);
alloff();


Now lets make a loop in which we put all leds (one by one) on

  for(k=0; k<10; k++)
    {
    ledon(k);
    delay(1000);
    alloff();
     }


The complete code would look like this:

// Charlieplexing on an Attiny 85
// Code by Luc Volders 2014

int pins[] = {0,1,2,3,4};
int i;
int j;
int k;
int slowdown2 = 2; // this delay should have a lower value when using less leds.
                              // for example 4 when using 12 leds
long int start=0;
long int eind=0;

const int ledpins[20][2] ={
  // this array contains the pins per led
  // edit the pin numbers to your own wiring
  {1,0},
  {0,1},
  {2,0},
  {0,2},
  {3,0},
  {0,3},
  {4,0},
  {0,4},
  {2,1},
  {1,2},
  {3,1},
  {1,3} ,
  {4,1},
  {1,4},
  {3,2},
  {2,3},
  {4,2},
  {2,4},
  {4,3},
  {3,4}
};

void setup()
{
  // start with putiing all leds off
  alloff();
}

void loop()
{

  for(k=0; k<10; k++)
    {
    ledon(k);
    delay(1000);
    alloff();
    }
}

void alloff()
// this shuts down all leds
{
  for(int i = 0; i < 5; i++)
  {
    pinMode (pins[i], INPUT);
  }
}

void ledon(int lednr)
// choose a led from the array on put it ON
{

  pinMode (ledpins[lednr][0], OUTPUT);
  digitalWrite (ledpins[lednr][0], HIGH);

  pinMode (ledpins[lednr][1], OUTPUT);
  digitalWrite (ledpins[lednr][1], LOW);
  delay(slowdown2);

}



And this makes programming the individual leds a lot easier and a lot less prone to errors.

I describe here the version for 20 leds but it can easily be adapted to 12 leds by just using pin numbers 0 to 3 and limiting the array to 12 items. That would give you an extra pin for attaching a button or sensor.

Nice all this theory. But what can you do with this.
The next episode shows you how to make a Larson scanner.

So till next time
have fun

Luc Volders

Friday, September 15, 2017

Charlieplexing

I really love the Attiny85 processor. This small processor has a lot of processing power (8 Mhz without any tricks) 5 I/O pins (6 if you do not need to reprogram the processor) and 8K memory. More as sufficient for a lot of projects. And best of all it only costs about a dollar.

However sometimes you run out of I/O pins. I needed to control 20 leds for a project I was making. The Tiny only has 5 I/O pins so that raised a problem. I could move over to a larger processor like the Atmega 328 which has 19 free to use I/O pins.But I wanted to stick by the Attiny85.


So here comes a technique that makes it possible to attach 20 leds to an Attiny 85, provided you can use all 5 I/O pins. The technique is called charlieplexing named after its evangelist Charlie Allen. 

First I'll give you the formula which enables you to detremine how many I/O ports you need for controlling a certain amount of leds:

X * X-1 =  number of leds that can be controlled

So with 3 I/O pins you can control  3 * 3-1 = 6 leds
Using 5 I/O pins you can control 5 * 5-1 = 20 leds.

How does charlieplexing work.

An I/O port can have the digital values 0 or 1. But there is a third state and that is called 3-state. This puts the port in a high-impedance state. So if we put an I/O port in 3-state modus it's value is not 0 and not 1.  We will use that with charlieplexing.

So lets first have a look on how we attach 2 leds to an Attiny 85



Nothing special here. Just 2 I/O ports with each a led attached.

So to connect 5 leds to an Attiny85 you can use the following circuit.



Again nothing dramatic.

But now we are going to do things differently. Lets first start simple and attach 2 leds to an Attiny85 using the Charlieplexing technique. The wiring is now completely different.



So we do not attach both leds to ground but we connect the leds to the I/O pins and one led the other way round.

Now if we put a LOW singnal (0) to pin 5 and a High signal (1) to pin 6 one of the leds will light up. If we switch the HIGH and LOW signals the other led will light up. That is still easy to comprehend.

And here comes the trick. Look at the next scheme:



There you go. 6 Leds attached to 3 pins. Remember the formula: 3 * 3-1 = 6.

However there is a problem using this. We can put a HIGH signal at pin 5 and a LOW signal to pin 7. The current will however run through Led 1 and further to Led 3. And both Leds will light up. That is not what we want. We want to be able to light them up individually. Further problem is that the Attiny85 is not capable of supplying enough current for all leds at the same time. So how are we going to solve that ??? And that is where the software comes in.

How to adress the leds.

So let's get back to the first example with two leds Charlieplexed. 


  



Ok the circuit speaks for itself but now I am going to show you how to adress the individual leds.

Normally we put PWM0 to HIGH to set the first led on and put it to LOW to put the Led off. For the second led we would set PWM1 to HIGH to set the second led ON and LOW to put it off.

With Charlieplexing we need to do that differently. We are going to use the Attiny I/O pins to supply the needed current to the leds.


First step is to define the PINS as INPUT to make sure both leds are off.

int led1 = 0; // pen PWM0
int led2 = 1; // pen PWM1
pinMode(led1, INPUT)
pinMode(led2, INPUT)



Now to put the first led on use the following code:


  pinMode (led1, OUTPUT);
  digitalWrite (led1, HIGH);
  pinMode (led2, OUTPUT);
  digitalWrite (led2, LOW);


And to put led 2 on we use the following code:

  pinMode (led2, OUTPUT);
  digitalWrite (led2, HIGH);
  pinMode (led1, OUTPUT);
  digitalWrite (led1, LOW);


Really quite simple. We just reverse the + and Ground on the pins so that first the first led will turn on and then the second one.

This shows that it is impossible to have both leds on at the same time. For that problem is a solution that I will show you later on.

Ok, nice. But what is the practical use.

Well things change if we use 3 Pins of the Attiny. This gives us a lot more possibillities. With 3 pins we can attach 6 leds. Let's look at the schematics again.




As you can see we can attach 6 leds to 3 pins and even have 2 pins left on the Attiny85 to attach buttons or sensors etc.

LED 1 and LED 2 are attached to pins 5 and 6, LED3 and LED 4 are attached to pins 6 and 7 and LED 5 and LED 6 are attached to pins 5 and 7.

Using software we can adress the individual leds.

First step is to define all pins as an INPUT

int led1 = 0; // pen PWM0
int led2 = 1; // pen PWM1
int led3 = 2; // pen ADC1
pinMode(led1, INPUT); 
pinMode(led2, INPUT);
pinMode(led3, INPUT);


To put Led 1 on we use the next code:

pinMode (led1, OUTPUT);
digitalWrite (led1, HIGH);
pinMode (led2, OUTPUT);
digitalWrite (led2, LOW);

Led 2 can be put on with the following code:

pinMode (led2, OUTPUT);
digitalWrite (led2, HIGH);
pinMode (led1, OUTPUT);
digitalWrite (led1, LOW);


For putting Led 3 on we need the next code:

pinMode (led2, OUTPUT);
digitalWrite (led2, HIGH);
pinMode (led3, OUTPUT);
digitalWrite (led3, LOW);


And putting Led 4 ON done the reverse way as putting Led 3 ON.

pinMode (led3, OUTPUT);
digitalWrite (led3, HIGH);
pinMode (led2, OUTPUT);
digitalWrite (led2, LOW);



Led 5 is adressed in the following maner:

pinMode (led1, OUTPUT);
digitalWrite (led1, HIGH);
pinMode (led3, OUTPUT);
digitalWrite (led3, LOW);



And Led 6 is put on by the reversed code of Led 5

pinMode (led1, OUTPUT);
digitalWrite (led1, HIGH);
pinMode (led3, OUTPUT);
digitalWrite (led3, LOW);


After each led has been set on you NEED to use the following code to put it off again.

pinMode(led1, INPUT); 
pinMode(led2, INPUT);
pinMode(led3, INPUT);

You really need to use this last bit off code each time after putting a led ON. If you don't do that the leds will be ON in an uncontrollable way. More as one pin will be HIGH and that put's leds on in places where you do not want them to be on.

You will surely have noticed by now several things.

Firstly the leds are attached in pairs which makes it simple by reversing polarity on the Attiny pins to put them on and off.

Next you will have noticed that the software to control the leds is getting more complex. In this stage it is manageable. However when you are using 4 pins you can control 4 x 3 = 12 leds and with 5 pins we can control 5 x 4 = 20 leds. The code to adress all these leds individually will be very complicated and that is what we are going to adress in the next part of this story.

Before we go to the next part I am going to show you the circuit in which 5 pins of the attiny85 are used.

If you use just 4 pins of the Attiny85 there is 1 pin left to attach a button or a sensor (LDR, Temperature sensor or whatever). The advantage is obvious. However you can 'only' attach 4 x (4 - 1) = 12 leds.

Using all 5 pins of the Arduino we can control 5 x (5 - 1) = 20 leds. The disadvantage is that there are no pins left to measure something or attach anything else. The only control we can use is to attach a button to the RESET pin of the Attiny85 to restart the program.

The next circuit shows you how to attach 20 leds to the 5 pins of the Attiny85.





As you will understand, the software to control the leds will be much longer if we keep on using the methods described above.

I'll give you an example.

Let's first set all pins of the Arduino in the 3-state mode to make sure nu leds are on.

int led1 = 0; // pen PWM0
int led2 = 1; // pen PWM1
int led3 = 2; // pen ADC1
int led4 = 3; // pen ADC3
int led5 = 4; // pen ADC2
pinMode(led1, INPUT)
pinMode(led2, INPUT);
pinMode(led3, INPUT);pinMode(led4, INPUT);
pinMode(led5, INPUT);


First let us put Led 1 on.

pinMode (led1, OUTPUT);
digitalWrite (led1, HIGH);
pinMode (led2, OUTPUT);
digitalWrite (led2, LOW);


Next step is to put Led 2 on

pinMode (led2, OUTPUT);
digitalWrite (led2, HIGH);
pinMode (led1, OUTPUT);
digitalWrite (led1, LOW);


And now Led 13
pinMode (led2, OUTPUT);
digitalWrite (led2, HIGH);
pinMode (led5, OUTPUT);
digitalWrite (led5, LOW);


Turning Led 14 on is again the reverse from Led 13

pinMode (led5, OUTPUT);
digitalWrite (led5, HIGH);
pinMode (led2, OUTPUT);
digitalWrite (led2, LOW);

Again the rule applies that we have to turn every led off after we have put it on so that all lines are in 3 state mode again and no 2 leds can be uncontrolled on at the same time. Forget to do that and you are in for some really unpredictable results.

So to put 1 particular led on (and off again) we need 9 program lines. For putting all 20 led's on we will need therefore 20 x 9 = 180 program lines. That surely is prone to errors and typo's so that unpredicatble things can happen. There must be a simple solution to that.

And there is !!!

The next part of this story will show you how to simplify the software and how to have multiple leds on at the same time.At this time however you have enough background to start experimenting. Try for instance to make a program that puts all odd leds on and off again.

Till next time

Have fun

Luc Volders

Monday, September 4, 2017

IFTTT 4 - send a notification to my phone

This is the last in a 4 part story. And I urge you to read the previous stories before you go on if you did not have done so yet.

First tutorial was a general introduction to IFTTT Click here to read it.
Second tutorial was how to activate the Maker Channel on IFTTT so you can trigger it with an ESP8266. Click here to read the second tutorial.
Third tutorial tells how to attach a motion-sensor (PIR) to an ESP8266 and trigger IFTTT to publish a Tweet when someone entered your room. Here you can find that tutorial.
In this last story I am going to show you how you can send a notification to your phone if someone entered your room.



So that third story showed you how you can publish a tweet when someone entered your room. That worked flawlessly however as you can see from the screenshot Twitter will clutter up in a hurry when loads of motions are detected. And that's no fun. You might not determine anymore which is which. Besides that, you will have to have Twitter installed and active on your smart-phone to get the messages. And that might not always be the case. So let's see if we can get a more significant notice.

We are going to make a new recipe in IFTTT for this purpose.

So first log in at IFTTT (https://ifttt.com/)  like I showed you in the previous story you can read by clicking here.




First choose to make a new recipe.




Choose the Maker channel just like we did in the previous story. The difference is that you are already connected to the channel so you already have a key.


Choose the trigger just like last time. There is only 1 trigger for the Maker channel and that is "receive a web request"



Now give the trigger a name. Let's keep it easy. Last time we choose Motion Detected so call this trigger Motion detected 2. Chose create trigger and on to the next screen.



Choose the action channel for the "THAT" function and chose "If Notifications"



Here also we only have 1 choice for the action that follows and that is "Send a notification"

Complete the action by filling in an appropriate text that is going to be send. Just like last time I included the time stamp in the notification.


In this last step you can see the complete action scheme:
If "maker event Notion detected 2" then Send a notification.
Chose for create recipe.

That's it.


Now make sure that you have installed IFTTT on your smart-phone and as soon as movement is detected in your room you will see the led on your phone blink and you will here a notification sound. On the primary screen on your phone you will see in the upper-left corner that there was an "IF" message.



Now open the notification screen on your phone and you can see what the fuzz is all around.

The difference with the previous project is that this notification will only be send to YOUR phone. There is no cluttering up in Twitter anymore.
The drawback is that if you wipe the notification away there is no prove that something happened. In the previous project you would have prove to show that someone was in your room. And that prove would stay safely on Twitter for as long as you like. So chose which option is best for you. However you can instruct IFTTT to do both !!! Send a message to your phone and post a Tweet. Experiment and I am sure you will figure out how to do that with IFTTT.

Amazing isn't it. A two dollar device like the ESP-8266 is capable of sending a notification around the globe so you will know that some-one was in your room. And I am sure you can find lots of other purposes for this technique too. A few ideas come directly to my mind:
- Send a notification when someone opens the fridge door
- Send a notification when someone is at your front door
- Send a notification with the rain-sensor (read how to make one here)

Till next time
Have fun

Luc Volders

Tuesday, August 15, 2017

Painting packaging

As some of you will know my girlfriend is a painter. She makes oil-paintings in all kind of sizes and one of my favorite sizes are the miniatures.

She started with small paintings on cardboard of about 2 by 1,5 inch which you can find at her website by clicking here.

Now she has found an even smaller object to paint on: crown-caps







In the pictures above you can see an example of what she makes of a normal crown-cap. She uses oil-paint for durability. As you can imagine it takes a lot of work, a sharp eye and a steady hand to create one of these.

She sells them (for really moderate prices) and therefore we needed to find some kind of packaging for these miniatures.

Thats where the 3D printer comes in.



I designed a small holder to put the paintings in and printed it.

Don't look at the color. My 3D printer supplier delivered 8 spools of pink filament a for a ridiculous low price so at this time near all my designs will be in pink.


Pink is not the best color to display these and therefore she painted them black with acrylic paint which works magnificent with PLA.


Here is the end result when it is all put into a small jewellery case.

Till next time
have fun

Luc Volders

Tuesday, August 1, 2017

Learn Python

We are back from our annual holliday, and hollidays are special for us. Three weeks a year without friends, relatives and obligations. We do not plan where we go to, we just put all our stuff in our car and drive south. And each year we end up in a different part of France which is beautifull.

Three weeks without newspapers, magazines, television, radio, computers, internet and even our smart-phones are put off.

We are totally incommunicado, and we love it. We love camping, read a lot, walk for miles, visit historical villages and nature sites, eat in local restaurants and just have the time of our lives.

Only this year I sinned a bit: I took my Android Tablet with me. And a computer book !!!

The reason for this was that I have several Raspberry Pi's at home. They are being used as a Domotics system, an IP camera, a Media Station and a printer server. None of these are projects I devellopped myself. I just download the code and use it.

However I wanted to learn to use the Raspberry for my own projects. Especially the humble Pi-Zero which just costs 6 euro would be an excellent starting point. It is a full fledged Linux computer with I/O ports. Ideal for IOT projects.
Where to start.

Python

Python is a versatile programming language that is fully supported by the Raspberry. In the Raspberry Operating System: Raspbian (a spacial branch of Debian linux) Python 2.7 and 3 are incorporated as well as the Geany programming editor.

Python supports the Raspberry's I/O ports and has a library for the special raspberry camera. So the easiest way to start projects with a Raspberry would be by programming in Python.

Few years ago I wrote a G-Code interpreter (for 3D printing) in Python and a program that displayed Google Maps on a PC screen.

So I had some experience with Python on my Desktop PC but never really got a good grip on it. I searched for functions on the internet and stumbled on things by accident. That allowed me to write programs and see how wonderfull Python is. However I never really learned it the right way.

Python on an Android Tablet




Yes, indeed. There is a Python interpreter readily available for Android. Just download it from the Google Play store (it's free) and start programming.
You can find it here: https://play.google.com/store/apps/details?id=org.qpython.qpy3

Learning Python

So I wanted a thorough course in Python programming. And a few weeks before my holliday I bought the following book:




Sams Teach Yourself Python Programming for Raspberry Pi in 24 hours.

And I did !!!
I really learned to understand Python programming in 24 hour.

If you have no real structured experience in Python and, like me, have just been messing around, searching things on the internet, this book is just great.

There are 24 chapters. Each chapter is a lesson full with demo programs and excercises that can be done within an hour. Hence the name. Every evening when my girlfriend went to bed I spend an hour studying Python and I learned a lot !!

You learn Python from the beginning working with variables, strings and artithmetics. Then it goes on with loops.
You learn about the different types of arrays that are called Tuples, Lists and Dictionaries. You will learn about writing your own functions and using libraries and modules. And also about GUI programming and Game programming.

The book will teach you how to use internet functions like writing a mail program, parsing HTML pages and using web-sockets.

And last but not least important you will learn how to write your own web-server and how to use the Raspberry I/O pins. This last part makes it very interesting to use the Raspberry Pi for IOT projects.

Practicing

I had no Raspberry Pi with me on my holliday (my girlfriend would shoot me). However I was able to follow most of the lessons on the Android Tablet.
I learned a lot during these 3 weeks especially about structuring my programs and about the different array structures. Every evening I was sitting in my tent and followed one lesson

The book is also full of tricks and tips that you can otherwise only find by hours searching on the internet.

I do not allow advertisements on this web-log and I do not normally promote / plug products. This book has learned me a lot in a short time and that is why I want to mention it to you.

Highly Recommended

Now I want one of these:

https://pi-top.com/products/pi-top

Till next time.
Have fun

Luc Volders

Tuesday, June 6, 2017

Visible Feedback for Raspberry Assistant

Still playing with the Google Home Assistant that runs on one of my Rapberry Pi's. And while playing I realised I missed something. I am planning to build the Assistant into a dummy mannequin head or into a mirror. However when I speak the words 'OK Google' I do not have a visible feedback telling that the Raspberry Assistant is actually reacting, so I have no way to see if it was triggered.

What I need therefore is a led that goes on whenever the Assistant starts listening and goes off when the last sentences have been spoken by the Raspberry Assistant. That's a good way of getting a feedback.

The Google Assistant kit that was supplied by the Raspberry Magazine MAGPI does have a visible feedback in the form of a led. I am however using the Google SDK version which works different.

So switch over to the Magpi version you would say. However the Magpi version is triggered by a button and not by speaking to it and further it has a rather nasty voice when it does not understand something. Overall it is a lesser quality version as the Google SDK is.

So let's attach a led.

First step is to attach a LED to the Raspberry Pi.




The LED is attached to IO pin 18 and through a limiting resistor of 1K to ground. Thats all.
The Magpi version uses pin 25. So for avoiding future compatibility issues you could use pin 25. However make sure that you alter the software accordingly.

The Software Patch

The Raspberry Assistant is for the main part written in Python which is great for us, as this can be altered easily.

To adress the I/O pins of the Raspberry, what we need to do to control the LED, you will need to use the Python GPIO library.


There is however a small problem.

The Raspberry assistant runs from within an ENV. The GPIO library is not directly available in that ENV. So we first have to make it available.



Open the file-manager which can be found at the top-right part of your screen.



Goto  /home/pi/env/lib/python3.4/site-packages/


Make a new folder called RPi and copy the contents of  /usr/lib/python3/dist-packages/RPi to the new RPi folder.


The last step is to alter __MAIN___.PY so that it turns on the led when the conversation starts and turns it off again when it ends.
You can find this file here: /home/pi/env/lib/python3.4/site-packages/google/assistant


Double click on __main__.py and it will open in an editor. Now alter the file as in the source code below.  Do NOT copy the file below as it may have wrong indents.

WARNING:
Python is very picky about indenting.
The indents in this listing are SPACES not TABS !!!
If you mix the indenting the program will not work, so only use SPACES for indenting.


 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
#!/usr/bin/env python

# Copyright (C) 2017 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the 

"License");
# you may not use this file except in compliance with the 

License.
# You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, 

software
# distributed under the License is distributed on an "AS 

IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 

either express or implied.
# See the License for the specific language governing permissions 

and
# limitations under the License.


from __future__ import print_function

import argparse
import os.path
import json
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM)
GPIO.setup(18, 

GPIO.OUT)
GPIO.output(18, 

GPIO.LOW)

import google.oauth2.credentials

from google.assistant.library import Assistant
from google.assistant.library.event import EventType
from google.assistant.library.file_helpers import existing_file


def process_event(event):
    """Pretty prints events.

    Prints all events that occur with two spaces between each new
    conversation and a single space between turns of a conversation.

    Args:
        event(event.Event): The current event to process.
    """
    if event.type == EventType.ON_CONVERSATION_TURN_STARTED:
        print()
        GPIO.output(18, GPIO.HIGH)
    print(event)

    if (event.type == EventType.ON_CONVERSATION_TURN_FINISHED and
            event.args and not event.args['with_follow_on_turn']):
        print()
        GPIO.output(18, GPIO.LOW)    


def main():
    parser = argparse.ArgumentParser(
        formatter_class=argparse.RawTextHelpFormatter)
    parser.add_argument('--credentials', type=existing_file,
                        metavar='OAUTH2_CREDENTIALS_FILE',
                        default=os.path.join(
                            os.path.expanduser('~/.config'),
                            'google-oauthlib-tool',
                            'credentials.json'
                        ),
                        help='Path to store and read OAuth2 

credentials')
    args = parser.parse_args()
    with open(args.credentials, 'r') as f:
        credentials = google.oauth2.credentials.Credentials(token=None,
                                                            **json.load(f))

    with Assistant(credentials) as assistant:
        for event in 

assistant.start():
            process_event(event)


if __name__ == 

'__main__':
    main()

Choose File/save and all is done.

Let's look at the listing.

23 import RPi.GPIO as GPIO
24 GPIO.setmode(GPIO.BCM)
25 GPIO.setup(18, GPIO.OUT)
26 GPIO.output(18, GPIO.LOW)

Line 23 to 26 are new entered lines.
First the GPIO library is imported. The GPIO mode is set to BCM so the IO pins will match the Raspberry's layout. And then GPIO 18 is defined as an OUTPUT and set in LOW state so the LED will initially be off.

44    if event.type == EventType.ON_CONVERSATION_TURN_STARTED:
45        print()
46        GPIO.output(18, GPIO.HIGH)
47   print(event)
48
49   if (event.type == EventType.ON_CONVERSATION_TURN_FINISHED and
50            event.args and not event.args['with_follow_on_turn']):
51        print()
52        GPIO.output(18, GPIO.LOW)

This is where it all happens.
As soon as the conversation starts GPIO 18 will be set HIGH (on) and when the conversation finishes the GPIO 18 is set LOW again (off).

Remember that if you have chosen to put the led on GPIO 25 you will have to later the source code accordingly.

That is all folks.

Restart your Pi and restart the Assistant


Now when you say "OK Google" the led goes on and when the conversation ends the led goes off again. A nice visual feedback that shows that you pronounced "OK Google" the right way so the Assistant understands.

OK, I am off for the summer hollidays.
New stories will be posted in August or so.

Till then: have fun !!!

Luc Volders

Saturday, May 20, 2017

Google Home and the ESP8266

A few years ago there was a (now cult) tv series called Eureka. The series is about a small village in the middle of nowhere were America's most clever minds live and work. They build the most fantastic devices and do deep research on all kinds of subjects for the US government. Then a new sherrif arrives and they have to give him a house to live in. The doors of his house open automatically and in his house is an all-present computer to which he can talk to and give orders like 'do the lights on' or 'what is the temperature' etc. etc. The series ran from 2006 to 2012 (just 5 year ago) and was science fiction at its best.

And guess what, it is no longer science fiction. A computer in your house that you can talk to: that's the present !!!!

And we owe it to Google. I hesitate to admit it but I love Google. Everybody is nagging at them and yet they give us so much free to use tools and gadgets. Just look at the search engine, google drive, Blogger (on which this weblog is written if you haven't noticed), the office suite, google cardboard (check into that really !!!), Android and just now Google Home Assistant.



For those of you living under a rock I will explain brief what Home Assistant is. It is the house computer from Eureka. It is Google's answer to Alexa. It is a stand alone speaker system with a build-in microphone. Indeed no screen, no keyboard, no mouse. The device is attached to the internet (be it wired or wireless) and the microphone listens to a command that activates it. The command is "OK Google" and that is something we know from Android Phones. However this is much more advanced.

There are lists with questions (easily found on the internet) you can ask Home Assistant. Examples are calculations like 535 x 345 or how many kilometres in 6 miles, or who was the first president of the United Sates, or how long is the Great Chinese Wall, or count from 10 to 25 (and backwards) or how long will it take from Rotterdam to The Hague (by car, by train or by bycicle take your pick) or will I need an umbrella tomorrow. You can also ask to roll the dice, give a random number between any two figures or flip a coin. Let it play animal sounds. You can even set alarms and timers. And a really great feature is to tell it "Remember I put my keys on tha table" and ask a few hours later where your keys are.

Basically you can ask it anything you can ask Google on your computer, and then some. And all is done by speaking out the questions and you will be answered by a pleasant womens voice. Really Amazing.

Now this wonder device will set you back at the time of this writing about 129 Dollar. But it gets better.




To get things really rolling Google supplied a Do it Yourself kit based on a Raspberry free with number 57 of the MagPi magazine. Naturally the magazine is totally sold-out.

And still better. Google gave the complete SDK free, for everyone to use.

Actually it works better as the Raspberry version. There is no button needed to activate it. Hands free commanding !!! Next to that it reacts better to questions being split up in multiple frases, and it has a timer and alarm function.


So get your Raspberry Pi out. Buy a USB microphone or use a USB audio adapter, a speaker and an SD card and build yourself a Google Home Assistant for just a few Dollar. Just follow the instructions here:
https://developers.google.com/assistant/sdk/prototype/getting-started-pi-python/

I have to admit I have wasted hours of my time just asking it silly questions. And there are many pages on the internet dedicated to publishing all the questions you can ask. Just look at this sample:
http://notsealed.com/hey-google-home-voice-commands-easter-eggs.html

At this moment there are just a few tens of millions of the original devices sold only in the US and UK as it's only language at this moment is English.

Imagine the impact this will have on society. Just think of the possibillities for disabled persons. Just command the device to set the lights on, the temperature at a certain degree, de radio at your favorite broadcaster.


Now think what we as tinkerers/hackers can do with such a device in our home. We will make our complete home automation voice commanded.



IFTTT compatibility.

You can have your Google Home (including the Raspberry DIY unit) paired with IFTTT. And then suddenly a wealth of possibillities rises.

Command your Philips Hue lights, send a tweet by voice (works flawless believe me), control your Nest thermostat, control your TV with Chromecast, keep a list of notes etc. etc. etc.

And best of all: we can control our ESP-8266 with the Google Home Assistant through IFTTT.
And that is what this entry is going to show you.

Google Home ==> IFTTT ==> ESP8266

Requirements

To get this working we need to do several steps which I discuss into detail step by step.

- Install ESP-Basic on a NodeMcu or Wemos-D1
- Set up your ESP-8266 with some leds
- Program The ESP with a Basic Program.
- Open a communication port on your router
- Get a IFTTT account (if you do not have it already)
- Set up a few IFTTT recipes
- Command your ESP by voice.

Install ESP-Basic on a NodeMcu or Wemos-D1

Well I am not going to discuss that in detail here as I have already done that in a previous story on this weblog which you can re-read here.
http://lucstechblog.blogspot.nl/2017/03/back-to-basic-basic-language-on-esp8266.html

Set up your ESP-8266 with some leds

I am using leds for demonstration purposes. But as you have seen before on this weblog you can exchange the leds for relays like in this story http://lucstechblog.blogspot.nl/2016/09/esp-relayserver.html or by transistors for controlling led-strips, pumps, motors etc.  like in this story
http://lucstechblog.blogspot.nl/2016/05/esp8266-controlled-ledstrip.html.

In this setup I am attaching 6 leds which all will be individually controlled. But as you will see in the next parts of this story you can expand this easily or use a less amount easily.

The setup is very simple.






At 6 of the NodeMcu's I/O ports (D1, D2, D3, D5, D6 and D7) is a led attached through a delimiting resistor of 1K. The breadboard layout shows it all.

Program The ESP with a Basic Program.

The program is as said before written in ESP-Basic which is a fast and easy devellopping platform for all your ESP projects. It will even work on a ESP-01 which could give you 4 output ports (I'll be demonstrating that in an upcoming story). For convenience I am using a Wemos D1 mini (clone) here. You could also use a NodeMCU or an Adafruit Huzzah.




'-----------------------------
'init
'-----------------------------
io(po,d1,0)
io(po,d2,0)
io(po,d3,0)
io(po,d5,0)
io(po,d6,0)
io(po,d7,0)

msgbranch [mybranch]

textbox command

wait

[mybranch]

command = msgget("saywhat") 
command = replace(command 

, "." , " ")
print command
if command = "living room on" then
io(po,d1,1)
endif
if command = "living room off" then
io(po,d1,0)
endif

if command = "garage door open" then
io(po,d2,1)
endif
if command = "garage door close" then
io(po,d2,0)
endif

if command = "garage light on" then
io(po,d3,1)
endif
if command = "garage light off" then
io(po,d3,0)
endif

if command = "bathroom light on" then
io(po,d5,1)
endif
if command = "bathroom light off" then
io(po,d5,0)
endif

if command = "living room ceiling light on" then
io(po,d6,1)
endif
if command = "living room ceiling light off" then
io(po,d6,0)
endif

if command = "water pump on" then
io(po,d7,1)
endif
if command = "water pump off" then
io(po,d7,0)
endif

wait


Let us look at the most important parts of the source code.



msgbranch [mybranch]

textbox command

wait


After the init part where all IO ports are set as output and put off the program starts a MESSAGE BRANCH.
It waits till it gets a command from the internet and displays that command in a textbox on your webpage. This makes it easy to determine if your spoen commands are in the right way interpreted by Google Gome Assist.
If certain commands are always faulty interpreted you can check that here and alter the command in the IFTTT part (further on in this story).




[mybranch]

command = msgget("saywhat") 
command = replace(command 

, "." , " ")
print command
if command = "living room on" then
io(po,d1,1)
endif
if command = "living room off" then
io(po,d1,0)
endif


When a command has been received from Google Home Assist the program jumps to [mybranch]

The first thing that happens is to see if  -- saywhat -- has been received. You can alter that in the program to any other word you like which would give you a bit more security. If -- saywhat -- is not received the program will not do anything.

The next line is a bit tricky:
command = replace(command , "." , " ")

Web communication has a problem with spaces. So this line replaces spaces with dots. We are going to use this program also with another way to command the same ESP chip in a future story. That is
by accessing the chip by an Android App. This way you can command the chip from within your home with Google Home Assistant and from anywhere else in the world by a voice recognition APP on your Android Phone.

To see if everything went well the received command is printed on your webpage by the print command.

The last few lines decide which command has been received and accordingly put the accompaning I/O port on or off.

That is all folks !!

Just for testing purposes I wrote a small program that only tests which command is received and prints that on your screen.


msgbranch [mybranch]

textbox command

wait

[mybranch]
command = msgget("saywhat") 
command = replace(command 

, "." , " ")
print command
wait


Use this for testing purposes just to see if your commands come through well.

Open a communication port on your router

First thing to do is to give your ESP a name and a fixed IP adress on your local network.
If for whatever reason your router crashes and gets online again, or your ESP crashes or gets powered down, it will get the same IP adress when it reboots.



So delve into your router (mostly accessible by local IP adress 192.168.1.1) and look at your connected devices. Mine looks like above.

The lower icons are the wired apparatus and as you can see it is my computer (Nescio), printerserver (actually a Raspberry) called Epson as it is connected to my Epson printer, my Buffalo Nas, my Domoticz domotica system and a raspberry. The last one is my DIY Google Home.

The top line icons are my wireless apparatus. There you can see a Thermometer (an ESP with a DS-18b20) and a device called 165. That last one is the ESP this all is about. I named it 165 as this is its IP adress and e4asily remembered.



By clicking on the name label I get information, can alter its name and can edit the check-box which gives it a fixed IP adress (Static DHCP).

Now all your local network settings are done.

As stated before normally you access your ESP from within your local network. However Google Home will need to access it through IFTTT fromthe outside world. This means that you should open a door (just like in your home) to get commands from the big wide world into your local ESP.
This is called port-forwarding.

This is the tricky part. I can only give you general directions on how to do this as all routers have different instructions on how to activate Port

Forwarding.

ESP-Basic generally uses port 80 for communication with the your network.
So that means that any command you send to the ESP (or from the ESP) is coming from the following local IP adress

XXX.XXX.XXX.XXX:80

As it is the general communication adress for all HTTP communication you normally ommit the port number (80) and just use the IP adress when accessing the ESP on your computer or phone or tablet.

However your local IP adress is not available from the outside world.

So we need to find your global IP adress. That is the adress your router uses to communicate with the outside world.
You can find that by pointing your web-browser at: http://whatismyipaddress.com/

Now you have to dig again into the setting pages from your router.
Look at something called port-forwarding.

There you can open a new port for the outside world.

In my router I have to give it a name. Next I give it the IP adress of the ESP and the ESP's port number which is 80.
Next I instruct it to send all communication from router port no 8085 to the ESP's port.

The router will most likely ask for a starting port number and an ending port number for your local and global ports. In both cases use the same. So start local 80, end local 80, start global 8085 and end global 8085. You can use many numbers as a port number but there are some restrictions. So delve into that by checkin information on the internet about this. This method allows you to open many specific ports for all kinds of projects.


 As you can see from my setup I have my Domoticz system at port 8081 and my ESP at port 8085

That is it.

Now the only thing left is to instruct your app or whatever you are using to crontrol the ESP to send or get the info from:
http://www.YYY.YYY.YYY.YYY:8085

The YYY part is off course the global internet adress

Be aware however that opening a port in your router might bring some security issuses as you are opening your router to the world.

The last steps

Now we have an ESP that can communicate with the outside world and a Google Home Assistant that can activate all kind of things by voice commands. The only thing to do is to have them talk to eachother.

There are two ways to do that.

First is the complicated way.
You could alter the Python code that is the motor of yout DIY Raspberry Home Assistant.  The advantage would be that you actually could use just your local IP adress and not have to connect your ESP to the outside world. This would certainly be a more secure way to achive communication.

However that would mean delving deep into the code and making a system that only works for your setup.

The second method is the easy way.
Have the Google Home Assistant talk to IFTTT and let IFTTT send through the Maker Channel commands to your ESP.

This has many advantages.
It is easy to implement. And it can not only be done by the DIY Home Assistant but actrually also by the Google Home Assistant. So wether you build a Home Assistant or buy one this will work.

This story uses the second method.

Get a IFTTT account (if you do not have it already)

I am not going to tell you how to do that as I have already wrote a detailed story on this which you can read here http://lucstechblog.blogspot.nl/2017/04/ifttt-if-this-then-that.html

Next connect to the Maker Channel. You can read how to do that here http://lucstechblog.blogspot.nl/2017/05/ifttt-part-2-maker-channel.html

Just be aware that IFTTT has altered the logo for the Maker Cahnnel and altered the total setup. But let that not frighten you as it is basically the same actions.

Set up a few IFTTT recipes

Almost done. These are the last steps.



First step is to choose New Applet on the right top of your screen. Then click on the blue IF.



Search for Google and the Google Assistant label will emerge and choose that.



Now you will be presented several options. As we want to turn switches ON and OFF choose the third option being -- Say a phrase with a text ingredient --



Fill the form in like the above example. You can use your own texts and commands as you like.
There is one special character in this App and that is the $.
The $ is required in any phrases you are going to fill in. It is later on substituted in the command that is send to the ESP by the word -- on -- or --off -- and will actually set the light on or off.

For demonstration excersises I advise you to use the setup as above.
Now choose Create Trigger at the Bottom.



Next step is to choose the then component so click the blue that.



Search for maker and Choose the Maker Webhooks.



Only one option here so choose that one.


Now complete the action field and fill in your global IP-adress which you found at http://whatismyipaddress.com/ put a column behind it immediately followed by the portnumer (being 8085) that you set in the router. Now click on the white button that says Add Ingredient and choose Textfield. Please make sure that no spaces are added in this line.
Also make sure that you really fill in the dots in living.room. and do not forget that last dot.

Some clarification.
IFTTT and your Google Home will not accept spaces being communicated. That is why I put dots in the place where the spaces would be.
And now you understand what the line in ESP-BASIC program is for.


command = replace(command , "." , " ")

This line filters out the dots and replaces them back into spaces.



And lastly alter the content type in text/plain. The method GET is the one we need. There is no body. All information is in the header.

The TextField will be substituted by the command we gave using the $ in the previous step.
Again carefully inspect the APP and make sure there is no space included between living.room. and the {{TextField}}
If there is a space your ESP-Basic program will not be able to recognise the command.

So if we say "Switch the living room light on" IFTTT will send the next command to our ESP:

http://xxx.xxx.xxx.xxx:8085/msg?saywhat=living.room.on

Now click on the button Create Action



IFTTT gives you a quick summerisation. Now click on the big blue Finish button.

And all is done.

You can check the complete IFFF command structure by clicking on the gear on the top right side and make alterations.

In just a few seconds your APP will be activated and you are set to go.

Test this thoroughtly and try to understand what is happening.
If you do understand how it works you can make the rest of the APP's in IFTTT to get the other led's running.

Command your ESP by voice.



Every thing is set now. Above you can see my setup. I am looking for some kind of casing however I want it to be special. Like a womens head used in clothes-shops or a crystal ball or something like that.

The only thing you have to do is just say the Magic Words: OK Google
And wait a second.

Then say: Switch the living room light on

And the led should come on.



Just for fun look at the video demonstrating how it all comes together.
Ehhh and please do not comment on the mess.........



And just look at that. More fun coming up.
I connected Raspberry Home Assistant through IFTTT with my Domoticz system. So now I am not only able to connect to ESP's but also to commercial available lightning systems like Philips Hue or Klik-Aan-Klik-Uit and their cheap counterparts from the local dollar stores. These systems are commanded by a 433 Mhz frequency which is send by my domotica system that gets its commands from Raspberry Home Assistant. But that is a whole other story which I will save for a next time.

Till then.
Have fun

Luc Volders