วันเสาร์ที่ 8 มีนาคม พ.ศ. 2557

Home heating automation with a Raspberry Pi and a smartphone

Home heating automation with a Raspberry Pi and a smartphone


In this article we explore the possibilities of using a Raspberry Pi for the remote control and monitoring of a home heating system using servo control, analogue to digital conversion, C programming and web development.

Servo control

We decided to use a servo device to control the on/off switch of the boiler. We could have used relay switches for the same purpose, but tried to stick to the principle of making no modifications to the boiler (as it’s owned by the landlord :D). The following image shows how the servo is mounted and the various states of control.
Our mini servo has reduced power requirements, so we could power it directly from the 5V pin of the Raspberry Pi. To create the needed pulse for servo control, we utilized wiringPi library’s softPWM implementation. Small glitches exist, but the accuracy is sufficient for this kind of control. The code below uses GPIO pin 0 as a PWM signal output to control the servo. We assume that wiringPi library is already installed.
pinMode(0, OUTPUT);
digitalWrite(0, LOW);
The “control” variable accepts integer values in the range of 180 to 194. The input to that variable will control the three positions of the switch. This will eventually be controlled from a web based user interface.

Sensors and ADC

Our servo device can now control the state of the boiler from our Raspberry Pi. However, when we remotely control the system, we cannot be sure that the servo worked as it should and that the boiler is in the state we want. For this reason we need a way to get feedback from the Raspberry Pi regarding the boiler’s state. The most straight-forward way to achieve this is to check the status of the LED indicator on the boiler. When the LED is on the boiler is turned on and when the LED is off the boiler is off. A simple LDR (Light Dependent Resistor) light sensor, in a dark box, mounted on the boiler’s two 7 segment LED displays should do the job. A LDR sensor is a variable resistor whose resistance depends on the amount of light arriving on it.
We also use two LM35 temperature sensors with analogue output; one for air temperature (mounted on the breadboard) and one for water temperature (mounted on a radiator).
You’ll need an analogue-to-digital converter (ADC) when using analogue sensors. We chose a BV4205 (a 10 channel I²C enabled IC) though others like the MCP3008 would also work. The analogue output from the three sensors gets converted to digital and is fed to the Raspberry Pi through the I²C bus. However, due to known issues with the I²C bus on the Raspberry Pi (see goo.gl/IQvN2O), a “patch” to slow down the clock of the I²C bus had to be applied before using the BV4205.
Below, we use the most basic parts of the code needed for communications over the I²C bus to read the analogue input of a sensor connected to channel 7 (use the same code for other channels). Similar code can be used for interaction with any I²C compatible device.
//Initialize I2C bus
int fd;
char *fileName = "/dev/i2c-1";
//Note: When using a Rev 1 Pi, use "/dev/i2c-0" 
int  address = 0x31;     
unsigned char buf[10]; 
fd = open(fileName, O_RDWR);
ioctl(fd, I2C_SLAVE, address);
//Select ADC channel 7
buf[0] = 1;    
buf[1] = 7;
write(fd, buf, 2);
//Start conversion
buf[0] = 2;
write(fd, buf, 1);
//Fetch result of conversion
buf[0] = 4;
write(fd, buf, 1);
read(fd, buf, 2);
unsigned short packedword;
packedword = (buf[0] <<8 buf="" pre="">

User interface

The following schematic shows the setup and how the devices connect and interact. A simple web interface provides easy access from web enabled devices. The web interface is mainly based on jQuery, PHP and MySQL.
Using PHP’s exec command, we get access to our two main executables that control the servo’s position and read sensor output. Ajax has been used extensively in order to achieve real-time monitoring of the boiler’s state and sensor readings. Furthermore, we calculate how long the system was on each day (in minutes) by analysing the light sensor’s output. The user is also presented with an SVG (d3.js library) graph of the air temperature for the last 24 hours with time resolution of one minute.
By exploiting data from the sensors, we could further extend the system and make it more intelligent by fully automating on and off events based on sensor output and specific usage profiles. For more information (code, schematics, pictures) about the project 
ref: http://www.themagpi.com/issue/issue-11/article/home-heating-automation-with-a-raspberry-pi-and-a-smartphone/

วันเสาร์ที่ 11 มกราคม พ.ศ. 2557

การติดตั้ง WiringPi เพื่อใช้งาน GPIO และเรียกใช้ผ่าน PHP บน Raspberry Pi

WiringPi เป็นไลบรารีที่ใช้ติดต่อกับพอร์ต GPIO (General Purpose Input/Output) ของ Raspberry Pi ถูกเขียนขึ้นด้วยภาษาซี พอร์ต GPIO เป็นพอร์ตอินพุตเอาต์พุตอเนกประสงค์ เราสามารถรับและส่งข้อมูลต่างๆได้ผ่านทางพอร์ตนี้ โดยในตัวอย่างวันนี้เราจะส่งค่าออกไปแสดงผลที่ LED และทดสอบรับค่ากลับจากการกดสวิตช์ จริงๆแล้วตัว WiringPi เป็นไลบรารีที่เราต้องเขียนโปรแกรมด้วยภาษาซีเพื่อเรียกใช้งาน แต่มันก็มีคำสั่งที่เป็นคอมมานไลน์ชื่อ gpio มาให้เราใช้งานด้วย คำสั่ง gpio นี้มีข้อดีตรงที่ว่ายูเซอร์ทุกคนในระบบสามารถเรียกใช้งานได้ ไม่จำกัดแค่ว่าต้องมีสิทธิเป็น root เหมือนกับการเรียกใช้ผ่าน shell ซึ่งข้อดีของคำสั่ง gpio ตรงนี้ทำให้เราสามารถเขียนคำสั่งด้วย PHP และเรียกใช้งานผ่านเว็บได้
อย่างแรกเริ่มจากการติดตั้ง GIT ลงไปก่อน
sudo apt-get install git-core
ถ้าหากว่าเกิดมี Error ขึ้นมาให้ลองทำการอัพเดทแพคเกจ และลองใหม่อีกครั้ง
sudo apt-get update
sudo apt-get upgrade
git clone git://git.drogon.net/wiringPi
cd wiringPi
git pull origin
เมื่อติดตั้งเรียบร้อย ลองทดสอบเรียกคำสั่ง gpio ขึ้นมาดูก่อนว่าใช้งานได้ไหม ถ้าไม่ได้ก็ตัวใครตัวมันครับ
gpio -v
ก่อนต่อวงจรเรามาดูตำแหน่งขาของ GPIO กันก่อนครับว่าอยู่ตรงไหนบ้าง จะเห็นว่ามีพอร์ต GPIO ให้เราใช้งานอยู่ทั้งหมด 17 ขา แต่วันนี้เราจะทดลองใช้ GPIO 7 สำหรับการทดสอบเรื่องอินพุต และใช้ GPIO 8 สำหรับการทดสอบเอาต์พุต
เริ่มต่อวงจรกันเลยครับ ในตัวอย่างเราจะใช้ LED เป็นเอาต์พุต และใช้สวิตกดติดปล่อยดับเป็นอินพุต
เมื่อต่อวงจรเรียบร้อยแล้วมาเริ่มทดสอบกันเลย เริ่มจากทดสอบเอาต์พุตก่อน โดยใช้คำสั่งต่อไปนี้ (สังเกตที่ LED จะติดและดับตามการส่งสัญญานที่เราส่งไป)
gpio -g mode 8 out //กำหนดให้ GPIO 8 เป็นขาเอาต์พุต
gpio -g write 8 1 //ส่งค่า Height ไปที่ขา GPIO 8
gpio -g write 8 0 //ส่งค่า Low ไปที่ขา GPIO 8
gpio -g mode 8 out
gpio -g write 8 1
gpio -g write 8 0
ทำการทดสอบอินพุตกันต่อ (ทดลองกดสวิตและอ่านค่าจาก GPIO 7)
gpio -g mode 7 in //กำหนดให้ GPIO 7 เป็นขาอินพุต
gpio -g read 7 //อ่านค่าจาก GPIO 7 โดยจะมีค่าเป็น 0 กับ 1
gpio -g mode 7 in
gpio -g read 7
ก่อนออกไปเที่ยว เดี๋ยวเราจะลองเรียกใช้งาน gpio โดยใช้ PHP กันดูบ้าง ซึ่งหลักการก็ง่ายๆ คือเราจะใช้ฟังชั่น exec() ของ PHP เรียกไปที่ /usr/local/bin/gpio ตรงๆเลยง่ายดี
สร้างไฟล์ gpio.php ที่ /var/www/gpio.php
sudo nano /var/www/gpio.php

exec("/usr/local/bin/gpio -g mode 8 out");
exec("/usr/local/bin/gpio -g mode 7 in");
if($_GET['gpio8'] == 1){
 exec("/usr/local/bin/gpio -g write 8 1");
 exec("/usr/local/bin/gpio -g write 8 0");
echo "GPIO  7 = ".exec("/usr/local/bin/gpio -g read 7");
เพียงเท่านี้เราก็สามารถควบคุม GPIO ของ Raspberry Pi ผ่านเว็บได้แล้ว ลองเปิดเว็บดูได้เลยครับ
นำมาจาก http://www.unzeen.com/article/2179/

วันศุกร์ที่ 1 พฤศจิกายน พ.ศ. 2556

Raspberry Pi as a Router

Raspberry Pis have started making there way into homes all across the world. When I got mine, the first thing I wanted to do was set it up as a router to replace my aging piece of D-link garbage.

This guide is somewhat geared towards those new to Linux so experienced users can feel free to skip around a bit and modify some of my commands.

The first step is to download and install Raspbian onto your SD card. You could just as easily use Debian, but Raspbian is preferred because it's optimized for the Pi. I'm using theDarkbasic minimal image because there's really no use for a GUI on a router and it would just hog resources but you can decide what flavor you like best.

I won't tell you how to install Raspbian because there's plenty of guides on the Raspbian site that explain it way better than I ever could.

From my experience, the Raspbian images you can download contain older versions of the Raspberry Pi firmware which is a problem because the kernel is not compiled with iptables support. Hexxeh to the rescue! The easiest way to install the new firmware is to use Hexxeh's rpi-updater which is available here with instructions as to how to install it. Remember to install ca-certificates before you wget the updater.

sudo apt-get update && sudo apt-get install ca-certificates

If I remember correctly, the script has one more dependency, but it will tell you what it is and it's available in the repositories and you can just apt-get it.

After your firmware has been updated, reboot the pi to activate it.

Here's where the fun begins, but first a bit of logic regarding my setup. As is shown in my video, the on-board NIC of the pi (eth0) is connected to the internet via my cable modem. My USB-NIC (eth1) is connected to my internal network, specifically in my case a wireless access point, but you could just as easily connect a switch if you need more wired ports.

As you can see in the video, I am using an apple branded USB-NIC because it's what I had lying around, but this is not a necessity. Debian has good support for lots of USB-NICs and in most cases they'll be recognized when you plug them in without any additional configuration.

The first step is to edit /etc/network/interfaces.

sudo nano /etc/network/interfaces

We want the internet facing NIC to get an address from our ISP via DHCP and our internal NIC to have a static address. I am using as my internal subnet but you can use any subnet you like as long as it is RFC 1918 compliant. Keep in mind a /24 (255 addresses) is most always big enough for a home network.

Here is what my /etc/network/interfaces file looks like. If you decide to change the internal subnet, you'll need to edit my addresses to suit your setup.

# interfaces(5) file used by ifup(8) and ifdown(8)

auto lo
iface lo inet loopback

#Onboard NIC connecting to the Internet
auto eth0
iface eth0 inet dhcp

#USB NIC serving as internal gateway
auto eth1
iface eth1 inet static
Save the file and restart networking (or reboot).

sudo /etc/init.d/networking restart

Next we need to install the DHCP server package on our Pi so we can allocate addresses to clients.

sudo apt-get install isc-dhcp-server

Now let's edit the DHCP server configuration file.

sudo nano /etc/dhcp/dhcpd.conf

The configuration files provides a lot of examples that are all commented out. Feel free to read them if you care to. Since this should be the only DHCP server on our network, let's make it authoritative. Uncomment out the authoratative line near the top of the file.

# If this DHCP server is the official DHCP server for the local
# network, the authoritative directive should be uncommented.

Next, lets add a new subnet. Scroll down to the bottom of the file and add something like this:

subnet netmask {
option broadcast-address;
option routers;
default-lease-time 600;
max-lease-time 7200;
option domain-name "local";
option domain-name-servers,;

Again, this is assuming a subnet. You'll need to change it if you've chosen a different subnet.

You'll also notice I'm using the Google public DNS servers, and If you prefer to use the DNS servers provided by your ISP, you'll need to change this line to reflect their addresses.

Save the file and restart the DHCP service.
sudo /etc/init.d/isc-dhcp-server restart
You should recieve two ok messages.

[ ok ] Stopping ISC DHCP server: dhcpd.
[ ok ] Starting ISC DHCP server: dhcpd.

If you receive an error about no interfaces being in the proper address space double check your configurations and make sure your static address on eth1 is in the same subnet as your DHCP subnet. if you need to make any changes you'll need to restart the relevant services.

At this point you should be able to plug a device into the USB NIC (eth1) interface of your pi and receive an IP address via dhcp. However, you won't be able to get any further on the network than your Pi itself. To solve this, we need to enable IP forwarding.

Guides I read said I needed to do one or the other of the following things, however, I had to do both. First run the following command:

sudo echo 1 > /proc/sys/net/ipv4/ip_forward

Next edit /etc/sysctl.conf and uncomment out the line that says net.ipv4.ip_forward = 1.

sudo nano /etc/sysctl.conf

# Uncomment the next line to enable packet forwarding for IPv4

Save the file.

The final step is to insert an iptables rule to allow NAT.

iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

Time for final testing. Plug a computer into the eth1 interface on your pi and plug the onboard NIC into your modem.

After the negotiation phase, your computer will pull an address and you should be able to access the internet! if it doesn't work, ssh to the Pi by using the address you gave eth1 ( in my case) and ensure that eth0 has a public address by running ifconfig.

sudo ifconfig -a
eth0      Link encap:Ethernet  HWaddr b8:27:eb:e8:4a:fe  
          inet addr:  Bcast:  Mask:
          inet6 addr: fe80::ba27:ebff:fee8:4afe/64 Scope:Link
          RX packets:1851717 errors:0 dropped:0 overruns:0 frame:0
          TX packets:680737 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:1493496473 (1.3 GiB)  TX bytes:131062180 (124.9 MiB)

eth1      Link encap:Ethernet  HWaddr 40:3c:fc:00:74:b0  
          inet addr:  Bcast:  Mask:
          inet6 addr: fe80::423c:fcff:fe00:74b0/64 Scope:Link
          RX packets:675292 errors:0 dropped:0 overruns:0 frame:0
          TX packets:1052136 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000 
          RX bytes:116080201 (110.7 MiB)  TX bytes:1474222354 (1.3 GiB)

lo        Link encap:Local Loopback  
          inet addr:  Mask:
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:2 errors:0 dropped:0 overruns:0 frame:0
          TX packets:2 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:152 (152.0 B)  TX bytes:152 (152.0 B)
If your eth0 still shows a private address it probably didn't renew when you moved it to your modem. Fix this by running:

sudo ifdown eth0 && sudo ifup eth0

Check your IP address by running ifconfig again and see if you can reach the internet. You may need to reboot your modem, however do not reboot your Pi for the reasons that are to follow.

If it's still not working, stop here and go back and make sure you've not missed any steps.

You should not reboot your Pi at this point because the iptables rules for nat we inserted earlier are not persistent and if you reboot they will be overridden by the default configuration (nothing). We can fix this by saving the rules and creating a little script to restore them as the network interfaces come up during boot.

First, save your iptables rules to a file.

sudo iptables-save > /etc/iptables.up.rules

You don't have to save them to /etc/iptables.up.rules, that's just where I save mine.

Next create a script in /etc/network/if-pre-up.d/ with the following contents:

sudo nano /etc/network/if-pre-up.d/iptables
#This script restores iptables upon reboot

iptables-restore < /etc/iptables.up.rules

exit 0

Change ownership and permissions of the script so it will run at boot.

sudo chown root:root /etc/network/if-pre-up.d/iptables && sudo chmod +x /etc/network/if-pre-up.d/iptables && sudo chmod 755 /etc/network/if-pre-up.d/iptables

Voila. You can now reboot and your iptables rules will stay persistent.

For some additional security, lets add some more iptables rules:

sudo iptables -A INPUT -s -i eth0 -j DROP
sudo iptables -A INPUT -s -i eth0 -j DROP
sudo iptables -A INPUT -s -i eth0 -j DROP
sudo iptables -A INPUT -s -i eth0 -j DROP
sudo iptables -A INPUT -s -i eth0 -j DROP
sudo iptables -A INPUT -s -i eth0 -j DROP
sudo iptables -A INPUT -i eth0 -p tcp -m tcp --dport 22 -j DROP
sudo iptables -A INPUT -i eth0 -p icmp -m icmp --icmp-type 8 -j DROP

This blocks access from RFC 1918 subnets on your internet (eth0) interface as well as ICMP (ping) packets and ssh connections.

Remember to save whenever you make changes!
sudo iptables-save > /etc/iptables.up.rules

If you want to see how many packets your firewall is blocking, run this command:

iptables -L -n -v

Chain INPUT (policy ACCEPT 215 packets, 23539 bytes)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 DROP       all  --  eth0   *           
  126 34570 DROP       all  --  eth0   *            
    0     0 DROP       all  --  eth0   *           
    0     0 DROP       all  --  eth0   *           
    0     0 DROP       all  --  eth0   *           
    0     0 DROP       all  --  eth0   *           
    0     0 DROP       tcp  --  eth0   *              tcp dpt:22
    0     0 DROP       icmp --  eth0   *              icmptype 8
    0     0 DROP       all  --  eth0   *           

Chain FORWARD (policy ACCEPT 15696 packets, 14M bytes)
 pkts bytes target     prot opt in     out     source               destination         

Chain OUTPUT (policy ACCEPT 191 packets, 25875 bytes)
 pkts bytes target     prot opt in     out     source               destination  

At this point, you should have a fully functional router that has extremely low power usage and some basic security.

In the future, I plan to add a switch to my network and add some 802.1q trunks to my USB Nic so I can have multiple LANs, but that's a different article.

วันจันทร์ที่ 28 ตุลาคม พ.ศ. 2556

8 Resources To Find Raspberry Pi Project Ideas

ref: http://www.efytimes.com/e1/fullnews.asp?edid=119611
8 Resources To Find Raspberry Pi Project Ideas  
Read on to find Raspberry Pi inspirations and ideas from 8 different resources.  
Rate this news:   (2 Votes)
Saturday, October 26, 2013:  Raspberry Pi is indeed the hot favorite amongst all the single-board computers and DIY electronics. It runs free and open source software and has huge support of hardware add-ons and peripherals, all thanks to the incredibly large and active user community. And there is indeed no end to the creativity that the creators have been using on it. Ad if you are also hunting for a project for your Pi, here we bring to you 8 resources to hunt down a Raspberry Pi project idea.
Open Source, Linux, Raspberry Pi, Raspberry pi project, raspberry pi inventions, Open source hardware, open source board, raspberry pi ideas

Adafruit Learning System: Adafruit Learning System is partially an online store, partially a knowledge base and partially a social community. Limor "Ladyada" Fried's Adafruit Industries is a hardware hacker's paradise. And while there's much more to Adafruit than Raspberry Pi-related products and information, the project ideas you'll find in the Learning System are particularly powerful because they're based around lessons that teach you the skills you need for more complex tasks down the road.

Embedded Linux Wiki: It's really a cliche to say that sometimes quality is more important than quantity, but, often, that really is the case. The RPi Projects section of the Embedded Linux Wiki may not be the largest list around, but that doesn't mean these aren't some of the more interesting ideas you'll run into. Plus, the tabular format with information about each project's difficulty makes finding a project suited to your skill level much easier.

The Magpi: What started as an idea being kicked around an online forum by some hardcore Raspberry Pi enthusiasts has grown into a print magazine, fan community, and a branded Raspberry Pi case. Issues of this magazine include much more than project ideas, so it's a great way to stay up on current Raspberry Pi news while looking for your next project idea.

MAKE: MAKE Magazine is now a well-established in the world of DIY electronics hobbies. The brand now includes the print magazine, Maker Faire, and tons of free online content. And, it's in that online content that you'll find some great project ideas for your Raspberry Pi board.

Raspberry Pi Foundation: With so many fans and user communities popping up all over, it's easy to forget that the official Raspberry Pi forums right on the Raspberry Pi website have a whole section dedicated to project ideas. It's an active group that's well worth checking out.

Raspberry Pi on Google+: Open source is alive and well on social networks. And, Raspberry Pi is certainly no stranger to things that people love to talk about on Google+. With a fan community boasting over 25,000 members, this is a great resource for connecting directly with some of Raspberry Pi's most vocal and active users while also picking up tips and ideas for your next project.

Raspberry PI Community Projects: The large, well-known media outlets generally provide consistent and informative data about Raspberry Pi, but overlook the small independent bloggers, and you might just miss out. This blog is updated regularly and provides posts not only about project ideas but also general interest information but also curates with all the passion and care that can make blogs so much fun to read.

Raspberry Pi Spy: This blog has purely been created for the love of Raspberry Pi. Spy delivers content on hardware of interest, tutorials, and project ideas related to Raspberry Pi boards. The posts are more inclined towards the tutorials than general project ideas but you will definitely find some inspiration here.

Courtesy: about.com 

วันพฤหัสบดีที่ 3 ตุลาคม พ.ศ. 2556

Easy code readSerial Port กันลืม

void loop
char c=Serail.read();

if (c=='1') digitalWrite(13,HIGH);
if (c=='a') digitalWrite(13,LOW);

วันจันทร์ที่ 30 กันยายน พ.ศ. 2556

Arduino - Ethernet Shield

Arduino - Ethernet Shield

How to build an arduino energy monitor - measuring mains current only. :ref http://openenergymonitor.org/emon/buildingblocks/how-to-build-an-arduino-energy-monitor-measuring-current-only?page=1

How to build an arduino energy monitor - measuring mains current only.

This little guide details how to build a simple electricity energy monitor on a breadboard that you could use to measure how much electrical energy you use in your home. It measures current and takes a set value for voltage (if your in the uk 230V) to calculate apparent power all the calculations are done on an arduino, although not as accurate as when a voltage measurement is taken, it is a method commonly used in whole house energy monitors for reasons of simplicity and lower cost. Here's how to do it:

Step One – Gather Components

You will need:
1x Arduino
Current sensing electronics
1x CT sensor yhdc SCT-013-000
1x Burden resistor 18 Ohms if supply voltage is 3.3V or 33 Ohms if supply voltage is 5V.
2x 10kOhm resistors (or any equall valued resistor pair upto 470kOhm)
1x 10uF capacitor
1x A breadboard and some single core wire.
Oomlout do a good arduino + breadboard bundle here £29

Step Two – Assemble the electronics

The electronics consist of the current sensor (which produce signals proportional to the current in the mains) and the sensor electronics that convert these signals into a form the Arduino is happy with.
For a circuit diagram and detailed discussion of sensors and electronics see:
Assemble the components as in the diagram above.

Step Three – Upload the Arduino Sketch

The Arduino sketch is the piece of software that runs on the Arduino. The Arduino converts the raw data from its analog input into a nice useful values and then outputs them to serial.
a) Download EmonLib from github and place in your arduino libraries folder.
Download: EmonLib
b) Upload the voltage and current example:
#include "EmonLib.h"                   // Include Emon Library
EnergyMonitor emon1;                   // Create an instance

void setup()
  emon1.current(1, 111.1);             // Current: input pin, calibration.

void loop()
  double Irms = emon1.calcIrms(1480);  // Calculate Irms only
  Serial.print(Irms*230.0);        // Apparent power
  Serial.print(" ");
  Serial.println(Irms);         // Irms

c) Open the arduino serial window
You should now see two columns of values. Apparent power on the left and rms current on the right.
Regeneractiv's picture

Re: How to build an arduino energy monitor - measuring current only

Guten Morning!
I translated this tutorial into German. It´s not perfect but I hope it could help someone.-->Link.
Ich hab´ den Tutorial übersetzt, ist sehr schlecht geschrieben, da Deutsch nicht meine Muttersprache ist, aber verständlich sollte es sein... für fragen: