Monday, December 22, 2014

60. Exploring the Pi B+'s Ports VI - Controlling Servos Using the MPU-6050

27,000 page views!!
Hopefully I'm getting a bit closer to a self-balancing platform.  The stage I'm at now effectively has the accelerometer signal being sent to the 2 servos, rotation of the MPU-6050 about its x-axis, rotating one servo, and rotation about the y-axis controlling the second servo.

Here's the code:


Here's the video:

The sensitivity can be changed by adjusting the code

Saturday, December 20, 2014

59. Exploring the Pi B+'s Ports V - Controlling Servos and Reading the MPU-6050

Controlling servos using an Arduino is very easy.  Remember the light follower at my post number 45, which used the Arduino Servo.h library HERE?

The Arduino chip is good at this because it can deliver what the servo needs - very accurate PWM (Pulse Width Modulation) signals.  This is not possible to do on a Pi (see the RasPi.tv article HERE) because there are so many routines running and interrupting. In any case, the Raspberry Pi has only one hardware and one software PWM output.

The way to do it on a Pi is to use the Adafruit 16 Channel 12 Bit PWM and Servo Driver Breakout Board which does all of the hard work while the Raspberry Pi just tells it what to do. This board is based on a PCA9685 chip which was actually designed to be an LED controller. It is a PWM driver, controlled by I2C with a fast built-in clock, capable of operating at frequencies up to 1MHz. The 16 channels allow up to 16 PWM devices to be connected - ideal for robotics with lots of servos. 

The board only requires a 3V3 power supply for the chip, GND, and two connections, SCL (the clock line) and SDA (the data line), both of which hang off the I2C bus.  There are 2 further ports for external power and GND for the servos, which the Raspberry Pi would not be able to deliver.  The Adafruit board cost £11.98 including delivery from ModMiPi.  I also bought 2 x YKS New NEW SG90 9g Mini Servo motors from Amazon for £2.30 (free delivery).  These have a 180 degree range - even better than the previous ones I used in the Light Follower, which can rotate about 135 degrees.

The photos below give an idea of the circuitry:
From above, you can see the Pi with the Cyntech paddle board, connected as before to the GY-521 breakout board with the MPU6050 (on the blue breadboard).  I have taken the I2C lines and the 3V3 power and GND from that to the Adafruit servo driver.  The external power to the Adafruit board comes from an adjustable Step Down Supply Power Module with a 4V to 40V input and a 1.5V to 35V output.  It is capable of supplying a current of 2A.  I bought it about a year ago for about £2.  That's it on the white breadboard at the top of the picture.  It is powered from a mains supply of nominal 12V (capable of up to 1 amp). 

I tuned the output of the step down module to 5V for the servos, using its adjustable potentiometerYou can see the 2 servos joined at right angles to each other on the left - each of them can draw currents of some hundreds of mA.  The servos are connected to channels 11 and 15 of the Adafruit board.

Using the command:

i2cdetect -y 1 (the 1 refers to Revision 2 or later Raspberry Pis)

the following output was printed on the terminal:

     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- UU -- -- -- -- 
40: 40 -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- 68 -- -- -- -- -- -- -- 
70: 70 -- -- -- -- -- -- --                       


This shows a map of the registers on the Pi's I2C bus.  Two extra entries at the hexadecimal addresses 0x40 and 0x70 show that two I2C devices (the 2 servos in this case) have been detected at those addresses. 
Here's the Python script which I put together from Andrew Birkett's and Adafruit's work.  This is another step on the way to controlling the servos from the signals from the MPU6050:


Note that the xrot and yrot outputs (rotations in degrees about the x- and y-axes respectively) which are printed on the screen at the beginning of the video, are calculated from accelerometer data only, even though the gyroscope data is read also.

And here's the video:
Hopefully I'm going in the right direction to make a self-balancing platform!!

Friday, December 12, 2014

58. Exploring the Pi B+'s Ports IV - Reading the MPU-6050 using Python

26,000 page views!!
The last post described the 3D wireframe demonstration of the MPU-6050's rotations (ie the GY-521 breakout board) about the x-, y- and z-axes, and other scripts which displayed the readout of quaternions etc.  Those test programs were written in the C++ programming language. 

This time test programs are written in Python, giving me a better chance of understanding what's going on!  The circuitry is identical to that used in the last post, and of course, the I2C interface has previously been enabled.

smbus is a Python module which allows SMBus (system management bus - a sub-set of the I2C protocol) access through the I2C interface on Linux hosts. This is the key module for Python access.

Reading Accelerometer Data


In this first program, in addition to reading the data from the accelerometer, the output values are sent to a web page, just for fun!  The address of the web page depends on the Pi's IP address, which can be found using the terminal command

ifconfig

and appending :8080 to the end.   For example,

http://ip-address-of-your-pi:8080

Here's the Python code for server.py:

Andrew Birkett's really neat code reads the accelerometer part of the MPU-6050 and prints out the x- and y-axis rotations which are calculated by the program.  The output via the web page looks like this:
x-rotation: 0.2 degrees.   y-rotation: -2.2 degrees.

The values of course change as the MPU-6050 is rotated about its x- and y-axes. for example:
x-rotation: 50.8 degrees.   y-rotation: 18.4 degrees.
The web page has to be refreshed to see new values.

Reading Gyro & Accelerometer Data

This program, Reading6050.py, also written by Andrew Birkett, looks like this:

The program produces results like this:
pi@raspberrypi ~ $ sudo python Reading6050.py
gyro data
---------
gyro_xout:  -202  scaled:  -2
gyro_yout:  -191  scaled:  -2
gyro_zout:  11  scaled:  0

accelerometer data
------------------
accel_xout:  176  scaled:  0.0107421875
accel_yout:  160  scaled:  0.009765625
accel_zout:  15364  scaled:  0.937744140625
x rotation:  0.596614942501
y rotation:  -0.656278927449
pi@raspberrypi ~ $ 
So what does the program do and what do these results mean?

Friday, November 28, 2014

57. Exploring the Pi B+'s Ports III - Connecting the MPU-6050 Inertial Measurement Unit to the I2C bus

Some time back (see HERE) I had this GY-521 breakout board connected to an Arduino.  This time it's connected to the Raspberry Pi through the Cyntech paddle board:
As before, moving the small breadboard about (it's a blue one this time) generates signals in the on-board gyroscope and accelerometer, which are read via the I2C interface (serial data line, SDA - GPIO2 and serial clock line, SCL - GPIO3) by the Raspberry Pi.

A video of the demonstration is shown below:
I used ShareX 9.4.2 free software with FFmpeg added to capture the Pi's desktop from my PC, and used Vimeo to embed the video.

In the video I ran 3 different programs, using the following commands: ./demo_dmp, ./demo_raw and ./demo_3d which I will explain later.


Enabling the I2C interface

  • Install the i2c-tools:
sudo apt-get install python-smbus
sudo apt-get install i2c-tools
  • Enable I2C and SPI protocols:
sudo nano /etc/modprobe.d/raspi-blacklist.conf
  • This will open the above file in a text editor, allowing the following lines to be commented out:
#blacklist spi-bcm2708
#blacklist i2c-bcm2708
  • Edit the following file as follows, to allow the I2C module to be started automatically on start up:
sudo nano /etc/modules
  • When opened in the editor, add the last line as follows:
i2c-dev
  • Add the ‘pi’ user to the I2C group:
sudo adduser pi i2c
  • Update the Pi to ensure that all the latest packages are installed:
sudo apt-get update
sudo apt-get upgrade
sudo apt-get dist-upgrade
  • Finally re-boot the Pi:
sudo reboot

The Pi will now automatically support I2C on startup.


Interfacing the MPU-6050

Make the connections as follows:
  • Pin 1 - 3.3V connect to VCC on the MPU-6050
  • Pin 3 - SDA connect to the MPU's SDA
  • Pin 5 - SCL connect to the MPU's SCL
  • Pin 6 - Ground connect to GND


Checking the 
Addresses of the I2C bus & the MPU-6050's Registers

Using the command:

i2cdetect -y 1 (the 1 refers to Revision 2 or later Raspberry Pis)

the following output was printed on the terminal:

     0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f
00:          -- -- -- -- -- -- -- -- -- -- -- -- -- 
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
30: -- -- -- -- -- -- -- -- -- -- -- UU -- -- -- -- 
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 
60: -- -- -- -- -- -- -- -- 68 -- -- -- -- -- -- -- 
70: -- -- -- -- -- -- -- --                       


The entry at the hexadecimal address 0x68 shows that an I2C device has been detected at that address.  The UU at 0x3b appears to be reserved by the kernel for a driver.

These addresses allow us to examine their contents.  For example, entering the command:

sudo i2cget -y 1 0x68 0x75

reads the contents of the address 0x68 of I2CBUS 1 (the 1 refers to a Rev 2 or later Raspberry Pi) and retrieves the value in the register 0x75, which has a default value the same as the address (I think it is called the WHO_AM_I register - this is where the device itself 'knows' where it is on the I2C bus), and so it returns the value:

0x68

This apparently indicates that everything is working properly. :)


The Test Programs

I don't pretend to fully understand these programs, which have been written in the C++ language by Richard G Hirst, and available at https://github.com/richardghirst/PiBits/tree/master/MPU6050-Pi-Demo, but the first one, demo_dmp outputs the 4 quaternion values, followed by the yaw, pitch and roll values corresponding to the position and movement of the GY-521 breakout board.

The second program, demo_raw outputs the values of accelerometer measurements in the x, y and z directions, followed by the gyroscope measurements in the x, y and z directions.

The third program, demo_3d plots the 3D geometrical wireframe object's orientation in space, based on the calculated values mentioned above.

What Next?

What I would like to do is use the calculated values to feed to a 2-servo combination to control a self-levelling platform.

I think this might be a bit ambitious, so if anyone out there has any ideas how I could do this, I would be very grateful for your suggestions.


Wednesday, November 12, 2014

56. Exploring the Pi B+'s Ports II - Pulse Width Modulation

25,000 page views!!
In a previous post, http://smokespark.blogspot.co.uk/2013/04/15-programming-attiny85-with.html I experimented with RGB LEDs and control of LED brightness using Pulse Width Modulation (PWM).  That post includes explanations of how our human Persistence of Vision (POV) enables us to perceive a flashing LED as having less than maximum brightness.  That was using the ATMega 328 (Arduino) chip to program an ATTiny85 microchip to produce Pulse Width Modulation.

The difference here, of course, is that we are programming the Raspberry Pi in the Python language.  Not only are there coding differences, but we are working with 3V3 from the Pi's GPIO logic levels instead of 5V.


The circuit is a bit simpler than the last post at
http://smokespark.blogspot.co.uk/2014/10/55-exploring-pis-gpio-ports.html.  The switches have been removed as there are now no input GPIO ports, only outputs corresponding to the red, green and blue anodes of the RGB LED.  So the RGB LED is wired exactly the same as before - with its common cathode going to GND through a 
325Ω resistor.  You may have noticed that I still have wires running to GPIO ports 21, 22 and 23.  These are not connected to anything on the breadboard - I just forgot to remove them when I took off the switches!

What the experiment does is simply to increase the brightness of the red LED from zero to maximum, decrease it back to zero, move on the green LED, do the same, and then do this all over again for the blue LED.  The routine is in an infinite loop, but can be terminated gracefully by pressing CTRL-C on the keyboard:




For this video, I turned the ambient lighting down, as the LED colours all look white to the camera, in bright light.  You can see that there is a little bit of flicker, and this is intentional.  With a frequency of 40 hertz (40 Hz), my personal vision can detect flicker when the LEDs are in the dim part of their cycle.  A higher frequency will easily remove this flicker.  




It's interesting that this looping program doesn't use much in the way of processor resources.  You can see from the above image of the Pi's desktop, that the Raspberry Pi's CPU indicator is fairly activity-free, presumably because the code keeps the processor in the idle state for most of the time with the sleep() command. 

This experiment has been using software controlled PWM.  There are some GPIO pins (GPIO12, GPIO13 & GPIO18 - although I have also seen GPIO18 described as the PWM pin*) which are labelled PWM and therefore seem to have a special role in pulse width modulation.  When I find out how and when to use these, I'll post it up.

* servos require accurately timed pulses - which software alone cannot always provide, but GPIO18 with special software can (not sure I understand the subtleties here).

Friday, October 31, 2014

55. Exploring the Pi B+'s GPIO Ports I - The J8 Header

24,000 page views!!
Before I start this blog post, I would like to acknowledge the great contribution to the subject by Alex Eames, of RasPi.TV, who has blogged most of what I have done below.  As usual I have described my take on the things that I learn, this time on the various lessons Alex has described.  Much of what follows here has been taken from Alex's work.  My record serves as a reference for myself, while hopefully being of possible use to other enthusiasts interested in exploring the Raspberry Pi.


As my Raspberry Pi Model A is dedicated to my PiBot, and my Model B is tied up with the windguru project (I have a duplicate system at home, as well as one at the yacht club), I had a good excuse to buy the latest Model B+ Pi (see description HERE).  The detailed differences and improvements on this latest model are explained elsewhere, but basically, there are now 40 pins on the GPIO header, and these are summarised below:

I have added in the alternative functions of ports where they apply, to Alex's diagram. I took advantage of the opportunity to dress my Pi up in a swanky hot-chilli red Pibow Coupé case (available from Pimoroni HERE), which protects it from dust and other hazards like spilled tea, falling screwdrivers, curious cats, etc.  The Pibow case has convenient openings for connections, and the opening for the 40 GPIO pins has the pin port numbers etched beside them:


I even went one step further and treated myself to a Cyntech B+ 40-way Paddle Board (HERE), which makes it easier to get access to the GPIO ports.  This board allows connection of jumper wires, by pushing the orange tabs down, inserting the wire (which needs to be stripped at the end to a length of about 10mm).  Pre-manufactured jumper wire connector ends are not long enough.  However, when stripped wire is connected, a very reliable connection is achieved:


I have connected the rainbow ribbon cable to the Pi's J8 header "the wrong way round" as it makes the whole experiment's footprint smaller.  I discovered that it is necessary to push the 40-pin connector onto the Paddle Board and through the Pibow case onto the Pi, very firmly, otherwise you can get a 'floating terminal', possibly made worse by an aerial effect from the ribbon cable.



What this Example Does:

There are 4 buttons, referred to as Button 0 (top) and Buttons 1, 2 and 3 at the bottom. These buttons are wired to GND on one side, and on the other terminal, connections are made to GPIO ports 20, 21, 22 and 23 respectively.  The RGB LED's common cathode runs to GND via a 325Ω resistor, so that not too much current is drawn from the Pi.  The red, green and blue anodes are wired to the Pi's GPIO ports 24, 25 and 26.


The Code Explained:

When the code runs, it firstly prints the message that it is waiting for Button 0 to be pressed to terminate the program.  If Button 1 is pressed, the red LED lights up, Button 2 illuminates the green LED and Button 3 switches the blue LED on.  These 3 can be pressed randomly ad nauseum, lighting up the respective LEDs.  When you get bored, you can press Button 0 and the program will terminate.  CTRL-C will also terminate the program.

Rather than go through the Python programs as I came across them on Alex's blog, I will start with a fairly advanced example of my own and try to explain what the code means:

Firstly, let's see what circuit this code works with.  The four buttons on the breadboard are Button 0 (at the top) then Button 1, Button 2 and Button 3 (at the bottom):


Let's look at the script in detail, so that all aspects of the code can be explained:


Lines 1 & 2:
1 #!/usr/bin/env python2.7
2 # script by Sparks N Smoke based on Alex Eames at http://RasPi.tv

These two lines, beginning with a #, are descriptive comments.  These comments are always a good idea to indicate the language, acknowledgements etc. However there's a bit more to it than that. the characters #! in Line 1 is what's known as a shebang (or a hashbang) - although it starts with a #, the normal indicator for a comment, the program loading software uses this information to run the script with the specified version of Python. The Pi currently comes with 2 versions of Python, so the line beginning with the shebang identifies which version is to be used and where it is on the Pi's file system.


Line 4: 

4 import RPi.GPIO as GPIO

This line imports the Python module RPi.GPIO and calls it GPIO for future reference in the script.


Line 5:

5 from time import sleep

This is an instruction to the Python interpreter to go to the Python module time and load the sleep part of it, for use later on.


Line 6:

6 GPIO.setmode(GPIO.BCM)

There are two possible modes of referencing the GPIO pins - GPIO.BOARD for pin numbering (see the pin chart above), and GPIO.BCM for Broadcom GPIO numbering.  The choice of numbering mode is usually a personal preference, but as I needed to refer to the GPIO numbers, I have used the GPIO.BCM mode.


Lines 8 to 11:

8 GPIO.setup(20, GPIO.IN, pull_up_down = GPIO.PUD_UP)                   # Button 0
etc
 

This line sets up the GPIO20 pin as an input, and invokes the in-built pull-up resistor.  In a similar way, lines 9, 10 and 11 do exactly the same thing for GPIO21GPIO22 and GPIO23.  These pins are where the 4 physical buttons are connected.


Lines 13 to 15:

13 GPIO.setup(24, GPIO.OUT)                                                                     # LED Red
etc

This line sets up the GPIO24 pin as an output.  In a similar way, lines 14 and 15 do exactly the same thing for GPIO25 and GPIO26.  These pins are where the respective anodes of the RGB LED are connected.

Lines 17 to 21:

17 def my_callback1(GPIO24):
18         GPIO.output(24, 1)                                                                     # Red ON
19         sleep(0.5)

20         GPIO.output(24, 0)                                                                     
# Red OFF
21         print "BUTTON 1 PRESSED - main thread interrupted by another thread"

These lines define a function called my_callback1 which puts the GPIO24 pin in a HIGH state, thus switching on the RED element of the RGB LED.  I have specified the argument (in the brackets) as the GPIO port, although the word "channel" which Alex uses, also works. Presumably the dummy value satisfies the need to have something there.  Line 18 keeps the state the same for half a second, Line 20 then puts GPIO24 in a LOW state, turning off the RED element and Line 21 puts the message on the screen to indicate that a particular button has been pressed.  


Similarly, lines 23 to 27 and 29 to 33 do the same for GPIO25 and GPIO26.  The functions my_callback1, my_callback2 and my_callback3 are only executed when other lines of code call for them by name.  However, when they are executed, they run in a different thread.  This means that two things are running at the same time.


Lines 35 to 37:

35 GPIO.add_event_detect(21, GPIO.FALLING, callback = my_callback1, bouncetime = 300)
etc

This line sets up the ability to detect an event on pin GPIO21 - Button 1, that event being the fall from a HIGH state to a LOW state, of pin GPIO21.  This is where the callback function my_callback1 is invoked.  A further interesting argument is bouncetime = 300.  What this does is to compensate for switch bounce, where the switch actually makes contact more than the intended once per press.  If there are any bounces within 300 milliseconds (in this case), they will be ignored.

Lines 36 and 37 set up event detection for GPIO22, (Button2) and GPIO23
 (Button 3)

Lines 39 to 48:

39 try:

40     print "Main thread waiting for falling edge on port 20 - ie BUTTON 0"

41     GPIO.wait_for_edge (20, GPIO.FALLING)

42     print "Falling edge on port 20 detected. BUTTON 0 PRESSED"                                

44 except KeyboardInterrupt:

45     GPIO.cleanup() # Reset ports on CTRL-C


47 finally:

48     GPIO.cleanup() # Reset on normal exit

This is the main "thread" of the program, where the Pi's processor is in a relatively idle state, just waiting for something to happen.  The event it is waiting for is when pin GPIO20 - Button 0, falls from its initial HIGH state to the LOW state, that is, when the button is pressed.

When Button 0 is pressed, the execution of the code jumps to Line 47 and 48, where all the GPIO ports are reset to an initial LOW state, ready for other programs to be executed without receiving a message stating that the port it wants to use is already in use.

There is an exception to this flow - when CTRL-C is pressed on the keyboard.  This is called a keyboard interrupt and it will terminate the program, but only after Line 45 is executed - cleaning up the GPIO ports.

The program uses the method known as Threaded Callback Interrupts where the callback functions run in a separate thread from the main program.  This is less demanding on the processor as most of the activity is in a fairly idle state.

An alternative and simpler method is to use Polling, where a while True loop keeps running until an event happens like a button press.  The CPU activity is shown in the bottom right of the Pi's desktop.  The image below shows the desktop for the current Threaded Callback Interrupts.  


Compare the CPU indicator with that for an earlier one-button Polling program:



This heavy use of the processor would presumably consume more power - a point that is important when using batteries.

Thanks Alex !

Tuesday, September 23, 2014

54. Raspberry Pi set up to continually display a dynamic web page

23,000 page views!!
The task is to have a screen displaying a web page continually.  The web page contains the ‘live’ data from a specific sailing club windguru station.  This data is displayed in graphical form and is updated every minute:
The windguru station is an anemometer which has been positioned at the top of a 10 metre flag pole, to measure wind speed and direction.  A temperature probe is included.  The device is positioned so that its calibrated direction is pointing to true north.  The signals from the anemometer are transmitted wirelessly from a battery-powered  transmitter beside the anemometer, to a unit in the club house which is wired to the wi-fi router.  Information is sent to the windguru server which delivers the above information to the web.
The Raspberry Pi and associated cables, WiFi dongle, case and ultra mini wireless keyboard and trackpad were purchased from Pimoroni for less than £100.  It’s a Model B+ which has a 700MHz CPU, 512MB RAM, micro SD slot, 4 USB ports and a full size HDMI port.  The NOOBS software allows a choice of Linux operating systems and resides on an 8 GB micro SD card. I chose the Raspbian Debian Wheezy version of Linux.  The Pi is powered via USB connection to the TV to which it is connected.  The video signals are sent to the TV via an HDMI connection.  The VESA mount allows the Pi in its case to be mounted at the back of a TV, thereby being totally concealed.
Normally the Pi will boot up to the command line prompt, requiring a username and password to be entered, followed by a command like startx to start a Windows-like desktop, or other application.  To display web pages, the on-board lightweight web browser, Midori, would normally have to be started manually and prompted with the required web address.
The requirement here is to by-pass the login process and the manual starting of Midori.

Steps to take are as follows:

a.    Download and install programs using the following commands:
sudo apt-get install matchbox
matchbox is a “very lightweight fullscreen-only kiosk-specialized window manager” which is needed to ensure that the Midori web browser displays in full screen.
sudo apt-get install x11-xserver-utils
This contains useful utilities which can be invoked, as shown below.

b.    Edit existing system files (using nano):
1.  /etc/network/interfaces
2.  /etc/profile/
3.  /etc/inittab
c.    Write a script:
The script I wrote is called autowindguru and it can be executed with the command line
xinit ./autowindguru
which is executed within the profile file.
1. interfaces contains the Wireless network/SSID and the wireless key.
An example of the content of this file is:

auto lo
iface lo inet loopback
iface eth0 inet dhcp

allow-hotplug wlan0
auto wlan0

iface wlan0 inet dhcp
wpa-ssid ###########
wpa-psk ##########  (actual codes are hidden here)
2. profile
I added, at the last line of this (quite long) file,
xinit ./autowindguru
to run the  autowindguru  script (see below) which I wrote to run the web page.
3. inittab
The following link was where I got the instructions to modify the inittab file:
4. autowindguru
I created a script which I named autowindguru  as follows:
#!/bin/sh
xset –dpms
xset s off
#unclutter &
matchbox-window-manager &
while true; do
midori –e Fullscreen –a http://www.clyc.info/wp-content/uploads/windguruPageLarge.htm
done

The url included above points to the web page windguruPageLarge.htm  which I developed and uploaded to the www.clyc.info server.
The xset lines invoke the x11-xserver-utils utility which was downloaded and installed earlier.  They prevent screen blanking due to inactivity.
unclutter has been commented out, but could be used to remove the mouse cursor if it became a nuisance.
The while true; do………done code opens the browser in a loop, so that “it will re-start itself if something crashes”.
Some of these tips came from the following link:

The Web Page

The web page to be displayed consists of a 2 x 2 table, with the top row containing the basic windguru web page on the left, and the specific windguru 8-day forecast on the right.

The bottom row includes Javascript for current moon phase (from MoonConnection) on the left and local tide times from tidetimes on the right.
There are 2 versions of the web page:
1.    one for 1366 x 768 pixel screens (windguruPage.htm), and
2.    one for 1920 x 1080 screens (windguruPageLarge.htm) – shown below:


The panels on the left hand side of this page are dynamic (live), while those on the right need to be refreshed daily.  Daily refreshing can be done by switching the TV off and on, to re-boot the Pi.

Here is a photo of the Raspberry Pi in its PiBow case, with optional VESA mounting plate (right), and the Rii Portable 2.4GHz ultra mini handheld rechargeable keyboard with touchpad (it even includes a laser pointer!):

The Pi Model B+ looks great in it's PiBow case

The wireless mini keyboard - a brilliant piece of kit - only 6 inches long!

PS - this all runs beautifully, but if you need to get in to the command line (LXTerminal), you have to enter Ctrl-Alt-F3, and then log in as usual, and run startx.