Difference between revisions of "Projets:Perso:2013:RaspEink FHEM"

From Electrolab
Jump to: navigation, search
(Created page with "== Introduction == The aim of the RaspEink project is to drive a small e-Paper display with a Raspberry Pi. Such a display can be used for many purposes. Here we will create ...")
 
m
 
(3 intermediate revisions by one user not shown)
Line 14: Line 14:
 
* Perl, required to run FHEM
 
* Perl, required to run FHEM
 
* Python for extraction of data from logfile and generation of a bitmap
 
* Python for extraction of data from logfile and generation of a bitmap
* Modified version of the demo driver to send bitmap to display.
+
* The [[Projets:Perso:2013:RaspEink|driver]] used to send bitmap to display.
  
  
Line 25: Line 25:
 
== Step 1: Setup the Hardware and test it ==
 
== Step 1: Setup the Hardware and test it ==
  
Follow the excellent guide "Epaper_RaspberryPi.pdf" from Embedded Artists which can be downloaded from their website:
+
Follow the steps from the following article first to install and test the display driver: [[Projets:Perso:2013:RaspEink]]
http://www.embeddedartists.com/products/displays/lcd_27_epaper.php
+
  
The document describes how to connect the display to the Raspberry, download, compile and run the demo software and driver. The demo software simply loops between two static logos. Once this works, we are ready for...
+
== Step 2: Install and set up FHEM ==
  
== Step 2: Modify the driver to accept external bitmaps ==
+
There are numerous guides on how to install FHEM on a Raspberry Pi. Here is one example: [http://binerry.de/post/30300770630/introduction-to-home-automation-with-raspberry-pi|Introduction to Home Automation with Raspberry Pi]
  
With the demo software working, it is time to modify the source code to make it load a BMP instead of the static logos. Please note that the modifications described below are only for educational purposes. Try them at your own risk. I assume no responsibility for any damage done by using these modifications nor do I guarantee that the modifications work.
+
One FHEM is running, you can set up your heating system. My system consists of 3xFHT thermostats for the rooms + acutators for the radiators, one S300 TH for measuring external temperature and humidity and a radio-controlled 220V switch FS20 for activating the control line of the heater itself. You can have a look at my [http://www.fhemwiki.de/wiki/Heating_Control_Basic|guide] for inspiration.
  
The only modifications to the code were done in '''main.c'''.
+
== Step 3: Adapt piper.py to your needs ==
  
You can download the modified source file here: [http://www.pozor.ch/raspeink/raspeink_main.c raspeink_main.c]. Rename it to main.c and replace the original file from Step 1.
+
Download the complete RaspEinkFhem archive including piper.py [http://pozor.ch/RaspEink.tar.gz here].
  
== Step 3: Compile the modified source code and test it ==
+
Piper.py uses a number of variables to adapt to your FHEM installation:
 
+
With the main.c file replaced, we have to compile again as described in the PDF guide from Step 1. Make sure you are in the same directory as main.c and type:
+
  
 +
Path to the fhem log files. Don't forget the "/" at the end
 
<pre>
 
<pre>
make
+
log_path = "/opt/fhem/log/"
 
</pre>
 
</pre>
  
 +
Names of the heating actuators (e.g. FHT). These have to match the room name of your logfile, e.g. <b>chambre</b>-2015.log.
  
 +
<i>exterior</i> is the name of the exterior temperature probe (e.g. S300 TH) log file.
  
== main.c changes explained ==
+
<i>heater</i> is the name of the switch (e.g. FS20) which activates the heating system.
  
Here is a quick rundown on the modifications:
+
<pre>
First, the following variables and local function were introduced:
+
room1 = "chambre"
 +
room2 = "sdb"
 +
room3 = "salon"
 +
exterior = "exterieur"
 +
heater= "Chauffage"
 +
</pre>
  
 +
Next, define the öetters used to identify each room on the display:
 
<pre>
 
<pre>
/******************************************************************************
+
symbol_room1 = "C"
* Local Functions
+
symbol_room2 = "B"
*****************************************************************************/
+
symbol_room3 = "S"
 +
symbol_exterior = "X"
 +
</pre>
  
uint8_t filebuffer[176][36] = {};
+
And lastly, the threshold values for the actuators, i.e. when do they switch on the heater (at 30% open) and when will they shut it down (at 20% open).
uint8_t buffer[176][33] = {};
+
<pre>
 +
actuator_high_room1 = 30
 +
actuator_low_room1 = 20
 +
actuator_high_room2 = 30
 +
actuator_low_room2 = 20
 +
actuator_high_room3 = 30
 +
actuator_low_room3 = 20
 +
</pre>
  
void readfile(FILE *f) {
+
== Step 4: Test piper.py ==
int x,y;
+
   
+
    fseek(f, 62, SEEK_SET);
+
    fread(filebuffer, 1, 176*36, f);
+
    fclose(f);
+
  
for(x=0; x<=176; ++x) {
+
Run piper.py with:
for(y=0; y<=33; ++y) {
+
buffer[x][y] = ~filebuffer[175-x][y];
+
}
+
}
+
  
}
+
<pre>
 +
python piper.py
 
</pre>
 
</pre>
  
''filebuffer'' will hold the BMP after it is loaded. ''buffer'' will hold the final image. With ''fseek'' we go to a specific postion in the file, more precisely to the start of the actual pixel data. This postion (62 in our case) depends on the version of BMP used. There are several versions and which one is used largely depends on the image manipulation software. The Wikipedia article about the [http://en.wikipedia.org/wiki/BMP_file_format BMP file format] gives a nice overview.
+
It should create an <i>output.bmp</i> with the current readings.
  
For the purpose of this software we are using monochrome BMP (i.e. with 1 bit per pixel). A test bitmap can be downloaded [http://pozor.ch/testimage.bmp here]. Such BMP can be created in GIMP for example by reducing the number of indexed colors to 2. After saving the bitmap, it is a good idea to open it in a Hex editor and verify the offset of the pixel data. This value is stored in position 0x0Ah. If it is not 62 (0x3Eh), you need to adjust this value above. If you don't, the image might show a shift.
+
== Step 5: Setup cron ==
  
The software currently does not check whether the BMP format is OK.
+
Cron can be used to periodically run <i>piper.py</i> to create the <i>output.bmp</i> followed by <i>epaper</i> to send the BMP to the display.
  
The ''for'' loops then simply flip and invert the pixel data.
+
Here is what my cron looks like for executing the above every 5 minutes:
 
+
The main method can then be replaced completely by this one:
+
  
 
<pre>
 
<pre>
/******************************************************************************
+
# m h dom mon dow command
* Main method
+
*/5 * * * * python /home/pi/raspeink/piper.py && /home/pi/raspeink/epaper /home/pi/raspeink/output.bmp > /home/pi/raspeink/cron.log
*****************************************************************************/
+
int main(int argc, char *argv[])
+
{
+
 
+
  uint8_t* pOldImg;
+
  char* path = "";
+
  FILE *f = NULL;
+
 
+
  if(argc == 1) {
+
path = "testimage.bmp";
+
printf("No file specified, loading testimage.bmp\n");
+
f = fopen(path, "rb");
+
  }
+
 
+
 
+
  if(argc == 2) {
+
path = argv[1];
+
printf("Loading %s\n", path);
+
f = fopen(path, "rb");
+
if(f == NULL) {
+
  printf("File not found, loading testimage.bmp\n");
+
  path = "testimage.bmp";
+
  f = fopen(path, "rb");
+
}
+
+
  }
+
 
+
 
+
  bsp_init();
+
 
+
  readfile(f);
+
 
+
  memset((uint8_t*)&PreloadImage[0][0], 0xff, 176*33);
+
  pOldImg = (uint8_t*)&PreloadImage[0][0];
+
 
+
 
+
    printf("Sending Image...\n");
+
    epd_DisplayImg(DISPLAY_IN_USE, (uint8_t*)&buffer[0][0], pOldImg);
+
    pOldImg = (uint8_t*)&buffer[0][0];
+
 
+
 
+
  printf("Done.\n");
+
  return 1;
+
}
+
 
</pre>
 
</pre>
 
== Step 3:
 
 
The functions above simply load the file after doing some basic error checks. If no file is mentioned as a parameter or the file is not found, a test bitmap is loaded (the bitmap can be downloaded [http://pozor.ch/raspeink/testimage.bmp here]).
 
 
If all compiles well, you can use the software now to load your own bitmap:
 
 
<pre>sudo ./epaper yourbitmap.bmp</pre>
 
 
== piper.py: Generating BMP ==
 

Latest revision as of 21:56, 16 July 2015

Introduction

The aim of the RaspEink project is to drive a small e-Paper display with a Raspberry Pi. Such a display can be used for many purposes. Here we will create a status display for FHEM, a well known home automation software.

Hardware

Software Overview

  • Raspian linux from official source
  • FHEM home automation software
  • Perl, required to run FHEM
  • Python for extraction of data from logfile and generation of a bitmap
  • The driver used to send bitmap to display.


Software diagram:

RaspEink diagram.jpg

The central piece of software is the Python program (piper.py). It processes the FHEM logfiles and extracts all required information (temperatures, valve positions, humidity and burner status). It then creates a bitmap from this information and saves it to a file. The driver, written in C, loads the BMP and sends it to the display through SPI. A cron job executes the two programs sequentially every 5-minutes.

Step 1: Setup the Hardware and test it

Follow the steps from the following article first to install and test the display driver: Projets:Perso:2013:RaspEink

Step 2: Install and set up FHEM

There are numerous guides on how to install FHEM on a Raspberry Pi. Here is one example: to Home Automation with Raspberry Pi

One FHEM is running, you can set up your heating system. My system consists of 3xFHT thermostats for the rooms + acutators for the radiators, one S300 TH for measuring external temperature and humidity and a radio-controlled 220V switch FS20 for activating the control line of the heater itself. You can have a look at my [1] for inspiration.

Step 3: Adapt piper.py to your needs

Download the complete RaspEinkFhem archive including piper.py here.

Piper.py uses a number of variables to adapt to your FHEM installation:

Path to the fhem log files. Don't forget the "/" at the end

log_path = "/opt/fhem/log/"

Names of the heating actuators (e.g. FHT). These have to match the room name of your logfile, e.g. chambre-2015.log.

exterior is the name of the exterior temperature probe (e.g. S300 TH) log file.

heater is the name of the switch (e.g. FS20) which activates the heating system.

room1 = "chambre"
room2 = "sdb"
room3 = "salon"
exterior = "exterieur"
heater= "Chauffage"

Next, define the öetters used to identify each room on the display:

symbol_room1 = "C"
symbol_room2 = "B"
symbol_room3 = "S"
symbol_exterior = "X"

And lastly, the threshold values for the actuators, i.e. when do they switch on the heater (at 30% open) and when will they shut it down (at 20% open).

actuator_high_room1 = 30
actuator_low_room1 = 20
actuator_high_room2 = 30
actuator_low_room2 = 20
actuator_high_room3 = 30
actuator_low_room3 = 20

Step 4: Test piper.py

Run piper.py with:

python piper.py

It should create an output.bmp with the current readings.

Step 5: Setup cron

Cron can be used to periodically run piper.py to create the output.bmp followed by epaper to send the BMP to the display.

Here is what my cron looks like for executing the above every 5 minutes:

# m h dom mon dow command
*/5 * * * * python /home/pi/raspeink/piper.py && /home/pi/raspeink/epaper /home/pi/raspeink/output.bmp > /home/pi/raspeink/cron.log