Project showcase
Wireless Widget

Wireless Widget © GPL3+

Imagine that your refrigerator contains inductive power to plug it smart widgets.

  • 4,249 views
  • 4 comments
  • 8 respects

Components and supplies

Ardgen mega
Arduino Mega 2560 & Genuino Mega 2560
×1
Ard wifi101
Arduino Wifi Shield 101
×1
OLED display i2C
×1
OLED display I2C
×1
Mfg p9025ac r evk
IDT Qi 5W Receiver Prototype Kit
×1
P9025AC-R-EVK – Qi 5W Receiver Prototype Kit
×1
P9038 r evk top view 0
IDT Qi 5W Transmitter Prototype Kit
×1
P9038-R-EVK – Qi 5W Transmitter Prototype Kit
×1
5V Power supply
×1
Magnet
×1
Cardboard
×1
Cardboard box
×1
Magnet
×8
USB power supply
×1
Paper sheet
×1
Sheet of paper
×1
USB cable type B
×1

About this project

In this video, I show a Wireless Widget dedicated to Weather on a fake refrigerator (make with a cardboard box).

How it Works

The Wireless Widget is held on the refrigerator thanks to 8 magnets (4 on the widget and 4 on the refrigerator).

To be powered, the Wireless Widget has a Qi receiver that gets the energy from a Qi transmitter in the refrigerator. The transmitter is powered thanks to a 5V battery for Smartphone.

When the Wireless Widget is powered, its arduino starts, connects to Wi-Fi, finds its location (thanks to the web service http://ip-api.com/), gets weather (thanks to the web service http://api.wunderground.com/weather/api), and shows the weather on its OLED display.

How Make It

On one side of a cardboard : glue an arduino mega with a Wi-Fi shield, an OLED display connected to the arduino (VCC => 5V, GNG => GND, SCL => pin 21, SDA => pin 20) and plug a USB cable to the arduino.

On the other side of this cardboard : glue 4 magnets, glue the Qi receiver and connect the 5V of the USB cable (red wire) to the OUT of the Qi receiver and the GND of the USB cable (black wire) to the GND of the Qi receiver.

On one side of the cardboard box : glue a sheet of paper.

Into the cardboard box : glue 4 magnets, fixe the Qi transmitter (without the glass plane) and connect an USB power supply to the Qi transmitter.

Finally

In this example, we have a weather widget, but we can design other (also based on Qi power and Wi-Fi) like a security camera, photo viewer, twitter display, ...

Code

WirelessWidget.inoC/C++
Program for the Arduino Mega
#include <SPI.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <EEPROM.h>


#define OLED_RESET 30
Adafruit_SSD1306 display(OLED_RESET);

#define NUMFLAKES 10
#define XPOS 0
#define YPOS 1
#define DELTAY 2

#define DISPLAY_CHAR_SIZE 6
#define TEMP_OFFSET_Y 22

#define ICON_RAIN 0
#define ICON_SNOW 1
#define ICON_CLOUD 2
#define ICON_CLOUD_SUN 3
#define ICON_SUN 4
#define ICON_LOAD 5
#define ICON_ERROR 6
#define ICON_NBR ICON_ERROR + 1

#define IMAGE_OFFSET_X 72
#define IMAGE_OFFSET_Y 8
#define IMAGE_HEIGHT 55
#define IMAGE_WIDTH  55
static const unsigned char PROGMEM images[][385] =
{ 
  // rain
  { 0x0,0x0,0x7f,0x0,0x0,0x0,0x0,
  0x0,0x3,0xff,0xc0,0x60,0x0,0x0,
  0x0,0x7,0xff,0xf3,0xfc,0x0,0x0,
  0x0,0x1f,0xff,0xff,0xff,0x0,0x0,
  0x0,0x3f,0xff,0xff,0xff,0x0,0x0,
  0x0,0x7f,0xff,0xff,0xff,0xf8,0x0,
  0x0,0x7f,0xff,0xff,0xff,0xfe,0x0,
  0x0,0xff,0xff,0xff,0xff,0xff,0x0,
  0x0,0xff,0xff,0xff,0xff,0xff,0x0,
  0x0,0xff,0xff,0xff,0xff,0xff,0x0,
  0x0,0xff,0xff,0xff,0xff,0xff,0x0,
  0x1,0xff,0xff,0xff,0xff,0xff,0x0,
  0x1,0xff,0xff,0xff,0xff,0xff,0x0,
  0x7,0xff,0xff,0xff,0xff,0xff,0xc0,
  0xf,0xff,0xff,0xff,0xff,0xff,0xe0,
  0xf,0xff,0xff,0xff,0xff,0xff,0xe0,
  0x1f,0xff,0xff,0xff,0xff,0xff,0xf0,
  0x1f,0xff,0xff,0xff,0xff,0xff,0xf0,
  0x1f,0xff,0xff,0xff,0xff,0xff,0xf0,
  0x1f,0xff,0xff,0xff,0xff,0xff,0xf0,
  0x1f,0xff,0xff,0xff,0xff,0xff,0xf0,
  0x1f,0xff,0xff,0xff,0xff,0xff,0xf0,
  0x1f,0xff,0xff,0xff,0xff,0xff,0xf0,
  0xf,0xff,0xff,0xff,0xff,0xff,0xe0,
  0x7,0xff,0xff,0xff,0xff,0xff,0xc0,
  0x3,0xff,0xff,0xff,0xff,0xff,0x80,
  0x0,0xff,0xff,0xff,0xff,0xfe,0x0,
  0x0,0x0,0x0,0x0,0x0,0x0,0x0,
  0x0,0x0,0x0,0x0,0x0,0x0,0x0,
  0x0,0x0,0x0,0x0,0x0,0x0,0x0,
  0x0,0x0,0x0,0x0,0x0,0x10,0x0,
  0x0,0x3,0x0,0x8,0x0,0x30,0x0,
  0x0,0x7,0x0,0x38,0x0,0x70,0x0,
  0x0,0xf,0x0,0x78,0x1,0xf0,0x0,
  0x0,0x1f,0x0,0xf8,0x3,0xf0,0x0,
  0x0,0x3f,0x1,0xf8,0x7,0xe0,0x0,
  0x0,0x7f,0x3,0xf8,0xf,0xe0,0x0,
  0x0,0x7f,0x3,0xf8,0xf,0xe0,0x0,
  0x0,0xfe,0x3,0xf8,0xf,0xe0,0x0,
  0x0,0x7e,0x3,0xf0,0xf,0xe0,0x0,
  0x0,0x7e,0x1,0xf0,0x7,0xc0,0x0,
  0x0,0x18,0x0,0xc0,0x1,0x0,0x0,
  0x0,0x0,0x0,0x0,0x0,0x0,0x0,
  0x0,0x0,0x0,0x0,0x0,0x0,0x0,
  0x0,0x0,0x20,0x1,0x80,0x0,0x0,
  0x0,0x0,0xe0,0x3,0x80,0x0,0x0,
  0x0,0x1,0xe0,0xf,0x80,0x0,0x0,
  0x0,0x3,0xe0,0x1f,0x0,0x0,0x0,
  0x0,0x7,0xe0,0x3f,0x0,0x0,0x0,
  0x0,0xf,0xe0,0x7f,0x0,0x0,0x0,
  0x0,0xf,0xe0,0x7f,0x0,0x0,0x0,
  0x0,0x1f,0xe0,0x7f,0x0,0x0,0x0,
  0x0,0xf,0xc0,0x7f,0x0,0x0,0x0,
  0x0,0xf,0xc0,0x3e,0x0,0x0,0x0,
  0x0,0x7,0x80,0x1c,0x0,0x0,0x0 }, 
  // snow
  { 0x0,0x0,0x0,0x30,0x0,0x0,0x0,
  0x0,0x0,0x0,0x38,0x0,0x0,0x0,
  0x0,0x0,0x1c,0x38,0x70,0x0,0x0,
  0x0,0x0,0x1e,0x38,0xf0,0x0,0x0,
  0x0,0x3,0x1f,0x39,0xe3,0x80,0x0,
  0x0,0x3,0x8f,0xbf,0xc3,0x80,0x0,
  0x0,0x3,0x87,0xff,0xc3,0x80,0x0,
  0x0,0x3,0x83,0xff,0x83,0x80,0x0,
  0x0,0xc3,0x81,0xff,0x3,0x8e,0x0,
  0x1,0xf3,0x80,0xfe,0x3,0x9e,0x0,
  0x0,0xfb,0x80,0x78,0x3,0xbc,0x0,
  0x0,0x7f,0x80,0x38,0x3,0xfc,0x0,
  0x0,0x3f,0x80,0x38,0x3,0xf8,0x0,
  0x0,0x1f,0x80,0x38,0x3,0xf0,0x0,
  0xf,0xff,0x80,0x38,0x3,0xff,0xe0,
  0xf,0xff,0xc0,0x38,0x7,0xff,0xe0,
  0xf,0xff,0xe0,0x38,0xf,0xff,0xc0,
  0x0,0x1,0xf0,0x38,0x1f,0x0,0x0,
  0x0,0x0,0xf8,0x38,0x3e,0x0,0x0,
  0x30,0x0,0x7c,0x38,0x7c,0x0,0x38,
  0x38,0x0,0x3e,0x38,0xf8,0x0,0x78,
  0x3e,0x0,0x1f,0x39,0xf0,0x0,0xf8,
  0x1f,0x0,0xf,0xbb,0xe0,0x1,0xf0,
  0xf,0x80,0x7,0xff,0xc0,0x3,0xe0,
  0x7,0xc0,0x3,0xff,0x80,0x7,0xc0,
  0x7,0xc0,0x1,0xff,0x0,0xf,0x80,
  0x7f,0xff,0xff,0xff,0xff,0xff,0xfe,
  0xff,0xff,0xff,0xff,0xff,0xff,0xfe,
  0xff,0xff,0xff,0xff,0xff,0xff,0xfc,
  0x3,0xe0,0x1,0xff,0x0,0x7,0xc0,
  0x7,0xc0,0x3,0xff,0x80,0x7,0xc0,
  0xf,0x80,0x7,0xff,0xc0,0x3,0xe0,
  0x1f,0x0,0xf,0xbb,0xe0,0x1,0xf0,
  0x3e,0x0,0x1f,0x39,0xf0,0x0,0xf8,
  0x3c,0x0,0x3e,0x38,0xf8,0x0,0x38,
  0x38,0x0,0x7c,0x38,0x7c,0x0,0x18,
  0x0,0x0,0xf8,0x38,0x3e,0x0,0x0,
  0x0,0x1,0xf0,0x38,0x1f,0x0,0x0,
  0x7,0xff,0xe0,0x38,0xf,0xff,0xe0,
  0xf,0xff,0xc0,0x38,0x7,0xff,0xe0,
  0xf,0xff,0x80,0x38,0x3,0xff,0xe0,
  0x0,0x1f,0x80,0x38,0x3,0xf0,0x0,
  0x0,0x3f,0x80,0x38,0x3,0xf8,0x0,
  0x0,0x7f,0x80,0x38,0x3,0xfc,0x0,
  0x0,0x7b,0x80,0x3c,0x3,0xbe,0x0,
  0x0,0xf3,0x80,0xfe,0x3,0x9e,0x0,
  0x0,0xe3,0x81,0xff,0x3,0x86,0x0,
  0x0,0x43,0x83,0xff,0x83,0x80,0x0,
  0x0,0x3,0x87,0xff,0xc3,0x80,0x0,
  0x0,0x3,0x87,0xfb,0xe3,0x80,0x0,
  0x0,0x3,0x8f,0x39,0xf1,0x80,0x0,
  0x0,0x0,0x1e,0x38,0xf0,0x0,0x0,
  0x0,0x0,0x1c,0x38,0x70,0x0,0x0,
  0x0,0x0,0x0,0x38,0x0,0x0,0x0,
  0x0,0x0,0x0,0x18,0x0,0x0,0x0 } ,
  // cloud
  { 0x0,0x0,0x0,0x0,0x0,0x0,0x0,
  0x0,0x0,0x0,0x0,0x0,0x0,0x0,
  0x0,0x0,0x0,0x0,0x0,0x0,0x0,
  0x0,0x0,0x0,0x0,0x0,0x0,0x0,
  0x0,0x0,0x0,0x0,0x0,0x0,0x0,
  0x0,0x0,0x0,0x0,0x0,0x0,0x0,
  0x0,0x0,0x0,0x0,0x0,0x0,0x0,
  0x0,0x0,0x0,0x0,0x0,0x0,0x0,
  0x0,0x0,0x0,0x0,0x0,0x0,0x0,
  0x0,0x0,0x0,0x0,0x0,0x0,0x0,
  0x0,0x0,0x3f,0xf0,0x0,0x0,0x0,
  0x0,0x0,0xff,0xfc,0x0,0x0,0x0,
  0x0,0x3,0xff,0xff,0x0,0x0,0x0,
  0x0,0x7,0xff,0xff,0x80,0x0,0x0,
  0x0,0xf,0xff,0xff,0xc0,0x0,0x0,
  0x0,0x1f,0xff,0xff,0xe0,0x0,0x0,
  0x0,0x3f,0xff,0xff,0xf7,0x0,0x0,
  0x0,0x7f,0xff,0xff,0xff,0xe0,0x0,
  0x0,0x7f,0xff,0xff,0xff,0xf0,0x0,
  0x0,0xff,0xff,0xff,0xff,0xf8,0x0,
  0x0,0xff,0xff,0xff,0xff,0xfc,0x0,
  0x0,0xff,0xff,0xff,0xff,0xfc,0x0,
  0x0,0xff,0xff,0xff,0xff,0xfe,0x0,
  0x1,0xff,0xff,0xff,0xff,0xfe,0x0,
  0x1,0xff,0xff,0xff,0xff,0xfe,0x0,
  0x1,0xff,0xff,0xff,0xff,0xfe,0x0,
  0x1,0xff,0xff,0xff,0xff,0xff,0x0,
  0x7,0xff,0xff,0xff,0xff,0xff,0xc0,
  0x1f,0xff,0xff,0xff,0xff,0xff,0xf0,
  0x3f,0xff,0xff,0xff,0xff,0xff,0xf8,
  0x3f,0xff,0xff,0xff,0xff,0xff,0xf8,
  0x7f,0xff,0xff,0xff,0xff,0xff,0xfc,
  0x7f,0xff,0xff,0xff,0xff,0xff,0xfc,
  0xff,0xff,0xff,0xff,0xff,0xff,0xfe,
  0xff,0xff,0xff,0xff,0xff,0xff,0xfe,
  0xff,0xff,0xff,0xff,0xff,0xff,0xfe,
  0xff,0xff,0xff,0xff,0xff,0xff,0xfe,
  0xff,0xff,0xff,0xff,0xff,0xff,0xfe,
  0xff,0xff,0xff,0xff,0xff,0xff,0xfe,
  0x7f,0xff,0xff,0xff,0xff,0xff,0xfc,
  0x7f,0xff,0xff,0xff,0xff,0xff,0xfc,
  0x3f,0xff,0xff,0xff,0xff,0xff,0xf8,
  0x1f,0xff,0xff,0xff,0xff,0xff,0xf0,
  0xf,0xff,0xff,0xff,0xff,0xff,0xe0,
  0x3,0xff,0xff,0xff,0xff,0xff,0x80,
  0x0,0x0,0x0,0x0,0x0,0x0,0x0,
  0x0,0x0,0x0,0x0,0x0,0x0,0x0,
  0x0,0x0,0x0,0x0,0x0,0x0,0x0,
  0x0,0x0,0x0,0x0,0x0,0x0,0x0,
  0x0,0x0,0x0,0x0,0x0,0x0,0x0,
  0x0,0x0,0x0,0x0,0x0,0x0,0x0,
  0x0,0x0,0x0,0x0,0x0,0x0,0x0,
  0x0,0x0,0x0,0x0,0x0,0x0,0x0,
  0x0,0x0,0x0,0x0,0x0,0x0,0x0,
  0x0,0x0,0x0,0x0,0x0,0x0,0x0 },
  // cloud and sun
  { 0x0,0x0,0x7,0x0,0x0,0x0,0x0,
  0x0,0x0,0xf,0x80,0x0,0x0,0x0,
  0x0,0x0,0x1f,0xc0,0x0,0x0,0x0,
  0x0,0x0,0x1f,0xc0,0x0,0x0,0x0,
  0x0,0x0,0x1f,0xc0,0x0,0x0,0x0,
  0x0,0x40,0x1f,0xc0,0x10,0x0,0x0,
  0x1,0xf0,0x1f,0xc0,0x7c,0x0,0x0,
  0x3,0xf8,0xf,0xc0,0xfe,0x0,0x0,
  0x3,0xfc,0x0,0x1,0xfe,0x0,0x0,
  0x3,0xfc,0x0,0x3,0xfe,0x0,0x0,
  0x1,0xfc,0xf,0x81,0xfc,0x0,0x0,
  0x0,0xf0,0x7f,0xf0,0x78,0x0,0x0,
  0x0,0x60,0xff,0xf8,0x70,0x0,0x0,
  0x0,0x63,0xff,0xfe,0x20,0x0,0x0,
  0x0,0x3,0xff,0xfe,0x0,0x0,0x0,
  0x0,0x7,0xff,0xff,0x0,0x0,0x0,
  0x0,0xf,0xff,0xff,0x80,0x0,0x0,
  0x0,0xf,0xff,0xff,0x80,0x0,0x0,
  0xe,0x1f,0xff,0xff,0xc7,0x0,0x0,
  0x3f,0x1f,0xff,0xff,0xc7,0xe0,0x0,
  0x7f,0x1f,0xff,0xff,0x1,0xf0,0x0,
  0x7f,0x1f,0xff,0xfc,0x0,0x70,0x0,
  0x7f,0x1f,0x80,0x70,0x0,0x30,0x0,
  0x7f,0x1c,0x0,0x0,0x38,0x0,0x0,
  0x3f,0x10,0x0,0x1,0xfe,0x0,0x0,
  0x0,0x0,0x0,0x3,0xff,0x0,0x0,
  0x0,0x0,0xff,0xc7,0xff,0x80,0x0,
  0x0,0x3,0xff,0xff,0xff,0xc0,0x0,
  0x0,0x7,0xff,0xff,0xff,0xc1,0x0,
  0x0,0xf,0xff,0xff,0xff,0xdf,0xe0,
  0x0,0x1f,0xff,0xff,0xff,0xff,0xf0,
  0x0,0x3f,0xff,0xff,0xff,0xff,0xf8,
  0x0,0x7f,0xff,0xff,0xff,0xff,0xfc,
  0x0,0x7f,0xff,0xff,0xff,0xff,0xfc,
  0x0,0x7f,0xff,0xff,0xff,0xff,0xfc,
  0x0,0xff,0xff,0xff,0xff,0xff,0xfe,
  0x0,0xff,0xff,0xff,0xff,0xff,0xfe,
  0x0,0xff,0xff,0xff,0xff,0xff,0xfc,
  0x0,0xff,0xff,0xff,0xff,0xff,0xfc,
  0x7,0xff,0xff,0xff,0xff,0xff,0xfc,
  0x1f,0xff,0xff,0xff,0xff,0xff,0xf8,
  0x1f,0xff,0xff,0xff,0xff,0xff,0xf0,
  0x3f,0xff,0xff,0xff,0xff,0xff,0xc0,
  0x7f,0xff,0xff,0xff,0xff,0xff,0x80,
  0x7f,0xff,0xff,0xff,0xff,0xff,0x80,
  0x7f,0xff,0xff,0xff,0xff,0xff,0x80,
  0xff,0xff,0xff,0xff,0xff,0xff,0x80,
  0x7f,0xff,0xff,0xfc,0xff,0xff,0x0,
  0x7f,0xff,0xff,0xf8,0xff,0xfe,0x0,
  0x7f,0xff,0xff,0xf0,0x7f,0xfe,0x0,
  0x7f,0xff,0xff,0xc0,0x3f,0xfc,0x0,
  0x3f,0xff,0x0,0x0,0xf,0xf0,0x0,
  0x1f,0xfe,0x0,0x0,0x0,0x0,0x0,
  0xf,0xf8,0x0,0x0,0x0,0x0,0x0,
  0x3,0xe0,0x0,0x0,0x0,0x0,0x0 },
  // sun
  { 0x0,0x0,0x0,0x38,0x0,0x0,0x0,
  0x0,0x0,0x0,0x7c,0x0,0x0,0x0,
  0x0,0x0,0x0,0x7c,0x0,0x0,0x0,
  0x0,0x0,0x0,0x7c,0x0,0x0,0x0,
  0x0,0x0,0x0,0x7c,0x0,0x0,0x0,
  0x0,0x0,0x0,0x7c,0x0,0x0,0x0,
  0x0,0x0,0x0,0x7c,0x0,0x0,0x0,
  0x0,0x60,0x0,0x7c,0x0,0xc,0x0,
  0x0,0xf0,0x0,0x7c,0x0,0x1e,0x0,
  0x1,0xf8,0x0,0x10,0x0,0x3f,0x0,
  0x1,0xfc,0x0,0x0,0x0,0x7f,0x0,
  0x0,0xfe,0x0,0x0,0x0,0xfe,0x0,
  0x0,0x7f,0x0,0x0,0x1,0xfc,0x0,
  0x0,0x3f,0x0,0x0,0x1,0xf8,0x0,
  0x0,0x1e,0x1,0xff,0x0,0xf0,0x0,
  0x0,0xc,0x7,0xff,0xc0,0x60,0x0,
  0x0,0x0,0x1f,0xff,0xf0,0x0,0x0,
  0x0,0x0,0x3f,0xff,0xf8,0x0,0x0,
  0x0,0x0,0x7f,0xff,0xfc,0x0,0x0,
  0x0,0x0,0xff,0xff,0xfe,0x0,0x0,
  0x0,0x0,0xff,0xff,0xfe,0x0,0x0,
  0x0,0x1,0xff,0xff,0xff,0x0,0x0,
  0x0,0x1,0xff,0xff,0xff,0x0,0x0,
  0x0,0x3,0xff,0xff,0xff,0x80,0x0,
  0x0,0x3,0xff,0xff,0xff,0x80,0x0,
  0x7f,0x83,0xff,0xff,0xff,0x83,0xfc,
  0xff,0x83,0xff,0xff,0xff,0x83,0xfe,
  0xff,0xc3,0xff,0xff,0xff,0x87,0xfe,
  0xff,0x83,0xff,0xff,0xff,0x83,0xfe,
  0x7f,0x83,0xff,0xff,0xff,0x83,0xfc,
  0x0,0x3,0xff,0xff,0xff,0x80,0x0,
  0x0,0x3,0xff,0xff,0xff,0x80,0x0,
  0x0,0x1,0xff,0xff,0xff,0x0,0x0,
  0x0,0x1,0xff,0xff,0xff,0x0,0x0,
  0x0,0x0,0xff,0xff,0xfe,0x0,0x0,
  0x0,0x0,0xff,0xff,0xfe,0x0,0x0,
  0x0,0x0,0x7f,0xff,0xfc,0x0,0x0,
  0x0,0x0,0x3f,0xff,0xf8,0x0,0x0,
  0x0,0x0,0x1f,0xff,0xf0,0x0,0x0,
  0x0,0xc,0x7,0xff,0xc0,0x60,0x0,
  0x0,0x1e,0x1,0xff,0x0,0xf0,0x0,
  0x0,0x3f,0x0,0x0,0x1,0xf8,0x0,
  0x0,0x7f,0x0,0x0,0x1,0xfc,0x0,
  0x0,0xfe,0x0,0x0,0x0,0xfe,0x0,
  0x1,0xfc,0x0,0x0,0x0,0x7f,0x0,
  0x1,0xf8,0x0,0x10,0x0,0x3f,0x0,
  0x0,0xf0,0x0,0x7c,0x0,0x1e,0x0,
  0x0,0x60,0x0,0x7c,0x0,0xc,0x0,
  0x0,0x0,0x0,0x7c,0x0,0x0,0x0,
  0x0,0x0,0x0,0x7c,0x0,0x0,0x0,
  0x0,0x0,0x0,0x7c,0x0,0x0,0x0,
  0x0,0x0,0x0,0x7c,0x0,0x0,0x0,
  0x0,0x0,0x0,0x7c,0x0,0x0,0x0,
  0x0,0x0,0x0,0x7c,0x0,0x0,0x0,
  0x0,0x0,0x0,0x38,0x0,0x0,0x0 },
  // load
  { 0x0,0x0,0x0,0x0,0x0,0x0,0x30,
  0x0,0x0,0x7,0xff,0xc0,0x0,0xf0,
  0x0,0x0,0x3f,0xff,0xfc,0x1,0xf8,
  0x0,0x1,0xff,0xff,0xff,0x3,0xf8,
  0x0,0x3,0xff,0xff,0xff,0xc7,0xf8,
  0x0,0xf,0xff,0xff,0xff,0xef,0xf8,
  0x0,0x1f,0xff,0xff,0xff,0xff,0xf8,
  0x0,0x3f,0xff,0xff,0xff,0xff,0xf8,
  0x0,0x7f,0xff,0xff,0xff,0xff,0xf8,
  0x0,0xff,0xff,0xff,0xff,0xff,0xf8,
  0x1,0xff,0xfc,0x0,0x7f,0xff,0xf8,
  0x3,0xff,0xf0,0x0,0xf,0xff,0xf8,
  0x7,0xff,0xc0,0x0,0x7,0xff,0xf8,
  0x7,0xff,0x80,0x0,0xf,0xff,0xf8,
  0xf,0xff,0x0,0x0,0x1f,0xff,0xf8,
  0x1f,0xfe,0x0,0x0,0x3f,0xff,0xf8,
  0x1f,0xfc,0x0,0x0,0x7f,0xff,0xf8,
  0x1f,0xf8,0x0,0x0,0xff,0xff,0xf8,
  0x3f,0xf0,0x0,0x0,0xff,0xff,0xf8,
  0x3f,0xf0,0x0,0x0,0xff,0xff,0xf8,
  0x3f,0xe0,0x0,0x0,0xff,0xff,0xf0,
  0x7f,0xe0,0x0,0x0,0x0,0x0,0x0,
  0x7f,0xc0,0x0,0x0,0x0,0x0,0x0,
  0x7f,0xc0,0x0,0x0,0x0,0x0,0x0,
  0x7f,0xc0,0x0,0x0,0x0,0x0,0x0,
  0x7f,0xc0,0x0,0x0,0x0,0x0,0x0,
  0x7f,0xc0,0x0,0x0,0x0,0x7,0xfc,
  0x7f,0xc0,0x0,0x0,0x0,0x7,0xfc,
  0x7f,0xc0,0x0,0x0,0x0,0x7,0xfc,
  0x0,0x0,0x0,0x0,0x0,0x7,0xfc,
  0x0,0x0,0x0,0x0,0x0,0x7,0xfc,
  0x0,0x0,0x0,0x0,0x0,0x7,0xfc,
  0x0,0x0,0x0,0x0,0x0,0x7,0xfc,
  0x0,0x0,0x0,0x0,0x0,0xf,0xfc,
  0x1f,0xff,0xfe,0x0,0x0,0xf,0xf8,
  0x3f,0xff,0xfe,0x0,0x0,0x1f,0xf8,
  0x3f,0xff,0xfe,0x0,0x0,0x1f,0xf8,
  0x3f,0xff,0xfe,0x0,0x0,0x3f,0xf0,
  0x3f,0xff,0xfc,0x0,0x0,0x7f,0xf0,
  0x3f,0xff,0xf8,0x0,0x0,0xff,0xf0,
  0x3f,0xff,0xf0,0x0,0x1,0xff,0xe0,
  0x3f,0xff,0xe0,0x0,0x3,0xff,0xc0,
  0x3f,0xff,0xc0,0x0,0x7,0xff,0xc0,
  0x3f,0xff,0xe0,0x0,0x1f,0xff,0x80,
  0x3f,0xff,0xfc,0x0,0x7f,0xff,0x0,
  0x3f,0xff,0xff,0xff,0xff,0xfe,0x0,
  0x3f,0xff,0xff,0xff,0xff,0xfc,0x0,
  0x3f,0xff,0xff,0xff,0xff,0xf8,0x0,
  0x3f,0xff,0xff,0xff,0xff,0xf0,0x0,
  0x3f,0xef,0xff,0xff,0xff,0xe0,0x0,
  0x3f,0xc7,0xff,0xff,0xff,0x80,0x0,
  0x3f,0x81,0xff,0xff,0xff,0x0,0x0,
  0x3f,0x0,0x7f,0xff,0xf8,0x0,0x0,
  0x1e,0x0,0x7,0xff,0xc0,0x0,0x0,
  0x18,0x0,0x0,0x0,0x0,0x0,0x0 },
  // error
  { 0x0,0x20,0x0,0x0,0x0,0x8,0x0,
  0x0,0x38,0x0,0x0,0x0,0x38,0x0,
  0x0,0x7c,0x0,0x0,0x0,0x7c,0x0,
  0x0,0xfe,0x0,0x0,0x0,0xfe,0x0,
  0x1,0xff,0x0,0x0,0x1,0xff,0x0,
  0x7,0xff,0x80,0x0,0x3,0xff,0xc0,
  0x7,0xff,0x80,0x0,0x3,0xff,0xc0,
  0xf,0xff,0xe0,0x0,0xf,0xff,0xe0,
  0x1f,0xff,0xf0,0x0,0x1f,0xff,0xf0,
  0x3f,0xff,0xf8,0x0,0x3f,0xff,0xf8,
  0xff,0xff,0xfc,0x0,0x7f,0xff,0xfe,
  0x7f,0xff,0xfe,0x0,0xff,0xff,0xfc,
  0x7f,0xff,0xfe,0x0,0xff,0xff,0xfc,
  0x3f,0xff,0xff,0x1,0xff,0xff,0xf8,
  0x1f,0xff,0xff,0xc7,0xff,0xff,0xf0,
  0xf,0xff,0xff,0xef,0xff,0xff,0xe0,
  0x7,0xff,0xff,0xff,0xff,0xff,0xc0,
  0x1,0xff,0xff,0xff,0xff,0xff,0x0,
  0x1,0xff,0xff,0xff,0xff,0xff,0x0,
  0x0,0xff,0xff,0xff,0xff,0xfe,0x0,
  0x0,0x7f,0xff,0xff,0xff,0xfc,0x0,
  0x0,0x3f,0xff,0xff,0xff,0xf8,0x0,
  0x0,0x1f,0xff,0xff,0xff,0xf0,0x0,
  0x0,0x7,0xff,0xff,0xff,0xc0,0x0,
  0x0,0x3,0xff,0xff,0xff,0x80,0x0,
  0x0,0x3,0xff,0xff,0xff,0x80,0x0,
  0x0,0x1,0xff,0xff,0xff,0x0,0x0,
  0x0,0x0,0xff,0xff,0xfe,0x0,0x0,
  0x0,0x1,0xff,0xff,0xff,0x0,0x0,
  0x0,0x3,0xff,0xff,0xff,0x80,0x0,
  0x0,0x3,0xff,0xff,0xff,0x80,0x0,
  0x0,0x7,0xff,0xff,0xff,0xc0,0x0,
  0x0,0x1f,0xff,0xff,0xff,0xf0,0x0,
  0x0,0x3f,0xff,0xff,0xff,0xf8,0x0,
  0x0,0x7f,0xff,0xff,0xff,0xfc,0x0,
  0x0,0xff,0xff,0xff,0xff,0xfe,0x0,
  0x1,0xff,0xff,0xff,0xff,0xff,0x0,
  0x1,0xff,0xff,0xff,0xff,0xff,0x0,
  0x7,0xff,0xff,0xff,0xff,0xff,0xc0,
  0xf,0xff,0xff,0xef,0xff,0xff,0xe0,
  0x1f,0xff,0xff,0xc7,0xff,0xff,0xf0,
  0x3f,0xff,0xff,0x1,0xff,0xff,0xf8,
  0x7f,0xff,0xfe,0x0,0xff,0xff,0xfc,
  0x7f,0xff,0xfe,0x0,0xff,0xff,0xfc,
  0xff,0xff,0xfc,0x0,0x7f,0xff,0xfe,
  0x3f,0xff,0xf8,0x0,0x3f,0xff,0xf8,
  0x1f,0xff,0xf0,0x0,0x1f,0xff,0xf0,
  0xf,0xff,0xe0,0x0,0xf,0xff,0xe0,
  0x7,0xff,0x80,0x0,0x3,0xff,0xc0,
  0x7,0xff,0x80,0x0,0x3,0xff,0xc0,
  0x1,0xff,0x0,0x0,0x1,0xff,0x0,
  0x0,0xfe,0x0,0x0,0x0,0xfe,0x0,
  0x0,0x7c,0x0,0x0,0x0,0x7c,0x0,
  0x0,0x38,0x0,0x0,0x0,0x38,0x0,
  0x0,0x20,0x0,0x0,0x0,0x8,0x0 }
};

#if (SSD1306_LCDHEIGHT != 64)
#error("Height incorrect, please fix Adafruit_SSD1306.h!");
#endif

#include <Adafruit_CC3000.h>
#include <ccspi.h>
//#include <SPI.h>
#include <string.h>
#include "utility/debug.h"

#define GET_IP_SERVER cc3000.IP2U32(192, 168, 1, 81);
#define PORT_SERVER 80

#define REFRESH_DELAY 1800000   // 30min

#define ADAFRUIT_CC3000_IRQ   3 
#define ADAFRUIT_CC3000_VBAT  5
#define ADAFRUIT_CC3000_CS    10
Adafruit_CC3000 cc3000 = Adafruit_CC3000(ADAFRUIT_CC3000_CS, ADAFRUIT_CC3000_IRQ, ADAFRUIT_CC3000_VBAT,
                                         SPI_CLOCK_DIVIDER); 

// #define WLAN_SSID       "YourWiFiSsid"           // cannot be longer than 32 characters!
#if ! defined(WLAN_SSID)
#error("Please define WLAN_SSID like the line above");
#endif
// #define WLAN_PASS       "YourWiFiPassword"
#if ! defined(WLAN_PASS)
#error("Please define WLAN_PASS like the line above");
#endif
// Security can be WLAN_SEC_UNSEC, WLAN_SEC_WEP, WLAN_SEC_WPA or WLAN_SEC_WPA2
#define WLAN_SECURITY   WLAN_SEC_WPA2

#define IDLE_TIMEOUT_MS  3000

#define LOCATION_WEBSITE "ip-api.com"
#define LOCATION_WEBPAGE "/json"

#define LAT_BUFFER_SIZE 20
char latBuffer[LAT_BUFFER_SIZE];
#define LAT_PREFIX_SIZE 6
static const char latPrefix[] = {'"', 'l', 'a', 't', '"', ':'};
#define LAT_LAST_CHAR ','

#define LON_BUFFER_SIZE 20
char lonBuffer[LAT_BUFFER_SIZE];
#define LON_PREFIX_SIZE 6
static const char lonPrefix[] = {'"', 'l', 'o', 'n', '"', ':'};
#define LON_LAST_CHAR ','

#define CITY_BUFFER_SIZE 30
char cityBuffer[CITY_BUFFER_SIZE];
#define CITY_PREFIX_SIZE 8
static const char cityPrefix[] = {'"', 'c', 'i', 't', 'y', '"', ':', '"'};
#define CITY_LAST_CHAR '"'

#define WEATHER_WEBSITE "api.wunderground.com"
#define WEATHER_WEBPAGE_BUFFER_SIZE 150
char weatherWebpageBuffer[WEATHER_WEBPAGE_BUFFER_SIZE];

// #define WUNDERGROUND_API_KEY "YourKey"  // get for free http://www.wunderground.com/weather/api/d/pricing.html
#if ! defined(WUNDERGROUND_API_KEY)
#error("Please define WUNDERGROUND_API_KEY like the line above");
#endif

#define TEMP_BUFFER_SIZE 13
char tempBuffer[TEMP_BUFFER_SIZE];
#define TEMP_PREFIX_SIZE 9
static const char tempPrefix[] = {'"', 't', 'e', 'm', 'p', '_', 'c', '"', ':'};
#define TEMP_LAST_CHAR_1 ','
#define TEMP_LAST_CHAR_2 '.'

#define ICON_BUFFER_SIZE 40
char iconBuffer[ICON_BUFFER_SIZE];
#define ICON_PREFIX_SIZE 8
static const char iconPrefix[] = {'"', 'i', 'c', 'o', 'n', '"', ':', '"'};
#define ICON_LAST_CHAR '"'

void setup(void)
{
  Serial.begin(9600);
  
  Serial.println("\nWelcome on Wireless Widget!"); 

  displayInit();
  diplayStatus("CONNECTION", "WIFI", ICON_LOAD); 
  Serial.print("Free RAM: "); Serial.println(getFreeRam(), DEC);
  
  Serial.println(F("\nInitializing cc3000..."));
  if (!cc3000.begin())
  {
    Serial.println(F("Couldn't begin()! Check your wiring?"));
    while(1);
  }
  
  Serial.print(F("Attempting to connect to ")); Serial.println(WLAN_SSID);
  if (!cc3000.connectToAP(WLAN_SSID, WLAN_PASS, WLAN_SECURITY)) {
    Serial.println(F("Failed!"));
    while(1);
  }

  /* Wait for DHCP to complete */
  Serial.println(F("Request DHCP")); 
  while (!cc3000.checkDHCP())
  {
    delay(100); // ToDo: Insert a DHCP timeout!
  }  
}

void loop(void)
{ 
  diplayStatus("LOCATION", "DATA", ICON_LOAD); 

  Serial.println(F("-------------------------------------"));
  
  if (getLocation()) {
    diplayStatus("WEATHER", "DATA", ICON_LOAD); 
    
    weatherWebpageBuffer[0] = '\0';
    strcat(weatherWebpageBuffer, "/api/");
    strcat(weatherWebpageBuffer, WUNDERGROUND_API_KEY);
    strcat(weatherWebpageBuffer, "/conditions/q/");
    strcat(weatherWebpageBuffer, latBuffer);
    strcat(weatherWebpageBuffer, ",");    
    strcat(weatherWebpageBuffer, lonBuffer);
    strcat(weatherWebpageBuffer, ".json");  
    Serial.print("\nweather webpage: ");Serial.println(weatherWebpageBuffer);  
    
    if (weatherFromMyServer()){
      displayInit();
      diplayWeather();
    }
    else{
      displayInit();
      diplayStatus("WEATHER", "DATA", ICON_ERROR); 
    }
  }
  else{
    displayInit();
    diplayStatus("LOCATION", "DATA", ICON_ERROR);  
  } 
  
  delay(REFRESH_DELAY);
}

void displayInit(){
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);
  display.clearDisplay();
  display.display();
}

void diplayWeather(){
  display.clearDisplay();
  
  // city
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(0,0);
  display.println(cityBuffer);
  display.display();
  
  // icon
  unsigned char icon = iconNameToNumber(iconBuffer);
  display.drawBitmap(IMAGE_OFFSET_X, IMAGE_OFFSET_Y, images[icon], IMAGE_WIDTH, IMAGE_HEIGHT, 1);
  display.display();
  
  // temp
  unsigned char tempLen = 0, i = 0;
  while (i < TEMP_BUFFER_SIZE) {
    if (tempBuffer[i++] == '\0'){
      break;
    }  
    tempLen++;
  }
  display.setTextSize(3);
  display.setTextColor(WHITE);
  display.setCursor(0,24);
  display.println(tempBuffer);
  display.display();
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(tempLen * DISPLAY_CHAR_SIZE * 3, TEMP_OFFSET_Y);
  display.println("o");
  display.display();
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(tempLen * DISPLAY_CHAR_SIZE * 3 + DISPLAY_CHAR_SIZE, TEMP_OFFSET_Y + 2);
  display.println("C");
  display.display();
}

void diplayStatus(char *title, char *message, unsigned char iconPosition){
  display.clearDisplay();
  
  // city
  display.setTextSize(1);
  display.setTextColor(WHITE);
  display.setCursor(0,0);
  display.println(title);
  display.display();
  
  // icon
  display.drawBitmap(IMAGE_OFFSET_X, IMAGE_OFFSET_Y, images[iconPosition], IMAGE_WIDTH, IMAGE_HEIGHT, 1);
  display.display();
  
  // temp
  display.setTextSize(3);
  display.setTextColor(WHITE);
  display.setCursor(0,24);
  display.println(message);
  display.display();
}

/*
* return 1 if data from the webservice is ok
* return 0 if data from the webservice is corupted
*/
unsigned char weatherFromMyServer(){
  uint32_t ip = 0;
  Serial.print(WEATHER_WEBSITE); Serial.print(F(" -> "));
  while (ip == 0) {
    if (! cc3000.getHostByName(WEATHER_WEBSITE, &ip)) {
      Serial.println(F("Couldn't resolve!"));
    }
    delay(500);
  }
  cc3000.printIPdotsRev(ip);Serial.println("");

  Adafruit_CC3000_Client www = cc3000.connectTCP(ip, 80);
  if (www.connected()) {
    www.fastrprint(F("GET "));
    www.fastrprint(weatherWebpageBuffer);
    www.fastrprint(F(" HTTP/1.1\r\n"));
    www.fastrprint(F("Host: ")); www.fastrprint(WEATHER_WEBSITE); www.fastrprint(F("\r\n"));
    www.fastrprint(F("\r\n"));
    www.println();
  } else {
    Serial.println(F("Connection failed"));    
    return 0;
  }
  
  unsigned char tempIndex = 0;
  char foundTemp = 0;
  unsigned char iconIndex = 0;
  char foundIcon = 0;
  unsigned long lastRead = millis();
  while (www.connected() && (millis() - lastRead < IDLE_TIMEOUT_MS)) {
    while (www.available()) {
      char c = www.read();
      
      // parse temp
      jsonParser(c, tempBuffer, TEMP_BUFFER_SIZE, &tempIndex, &foundTemp, tempPrefix, TEMP_PREFIX_SIZE, TEMP_LAST_CHAR_1, TEMP_LAST_CHAR_2, 0);
      // parse icon
      jsonParser(c, iconBuffer, ICON_BUFFER_SIZE, &iconIndex, &foundIcon, iconPrefix, ICON_PREFIX_SIZE, ICON_LAST_CHAR, ICON_LAST_CHAR, 0);

      lastRead = millis();
    }
  }
  www.close();
  
  if (foundTemp && foundIcon){
    Serial.print(F("Temp: "));Serial.println(tempBuffer);
    Serial.print(F("Icon: "));Serial.println(iconBuffer);
    return 1;
  }
  else{
    Serial.println(F("Error to get data from Weather"));
    return 0;
  }
}

/*
* return 1 if data from the webservice is ok
* return 0 if data from the webservice is corupted
*/
unsigned char getLocation(){
  uint32_t ip = 0;
  Serial.print(LOCATION_WEBSITE); Serial.print(F(" -> "));
  while (ip == 0) {
    if (! cc3000.getHostByName(LOCATION_WEBSITE, &ip)) {
      Serial.println(F("Couldn't resolve!"));
    }
    delay(500);
  }
  cc3000.printIPdotsRev(ip);Serial.println("");

  Adafruit_CC3000_Client www = cc3000.connectTCP(ip, 80);
  if (www.connected()) {
    www.fastrprint(F("GET "));
    www.fastrprint(LOCATION_WEBPAGE);
    www.fastrprint(F(" HTTP/1.1\r\n"));
    www.fastrprint(F("Host: ")); www.fastrprint(LOCATION_WEBSITE); www.fastrprint(F("\r\n"));
    www.fastrprint(F("\r\n"));
    www.println();
  } else {
    Serial.println(F("Connection failed"));    
    return 0;
  }
  
  unsigned char latIndex = 0;
  char foundLat = 0;
  unsigned char lonIndex = 0;
  char foundLon = 0;
  unsigned char cityIndex = 0;
  char foundCity = 0;
  unsigned long lastRead = millis();
  while (www.connected() && (millis() - lastRead < IDLE_TIMEOUT_MS)) {
    while (www.available()) {
      char c = www.read();
      
      // parse lat
      jsonParser(c, latBuffer, LAT_BUFFER_SIZE, &latIndex, &foundLat, latPrefix, LAT_PREFIX_SIZE, LAT_LAST_CHAR, LAT_LAST_CHAR, 0);
      // parse lon
      jsonParser(c, lonBuffer, LON_BUFFER_SIZE, &lonIndex, &foundLon, lonPrefix, LON_PREFIX_SIZE, LON_LAST_CHAR, LON_LAST_CHAR, 0);
      // parse city
      jsonParser(c, cityBuffer, CITY_BUFFER_SIZE, &cityIndex, &foundCity, cityPrefix, CITY_PREFIX_SIZE, CITY_LAST_CHAR, CITY_LAST_CHAR, 1);
      
      lastRead = millis();
    }
  }
  www.close();
  
  if (foundLat && foundLon && foundCity){
    Serial.print(F("City: "));Serial.println(cityBuffer);
    Serial.print(F("Lat: "));Serial.println(latBuffer);
    Serial.print(F("Lon: "));Serial.println(lonBuffer);
    return 1;
  }
  else{
    Serial.println(F("Error to get data from location"));
    return 0;
  }
}

void jsonParser(char c, char *buffer, int bufferSize, unsigned char *index, char *found, const char *prefix, int prefixSize, char lastChar1, char lastChar2, unsigned char toUpperCase){
  if ((*index) < bufferSize){
    buffer[(*index)++] = c;  
  }
  else if (! *found){
    for (int i = 0; i < bufferSize - 1; i++){
      buffer[i] = buffer[i + 1];
    }  
    buffer[bufferSize - 1] = c;
    
    char prefixFound = 1;
    int i = 0;
    if (prefixSize > bufferSize){
      prefixFound = 0;  
    }
    while ((i < prefixSize) && prefixFound){
      if (buffer[i] != (prefix[i++])){
        prefixFound = 0;
      }  
    }
    
    if (prefixFound){
      *found = 1;
      // prefixABClastchar => ABC\0
      for (int j = 0; j < prefixSize; j++){
        for (int i = 0; i < bufferSize - 1; i++){
          if ((j == prefixSize - 1) && (toUpperCase) && ( 'a' <= buffer[i + 1]) && (buffer[i + 1] <= 'z')){
            buffer[i] = buffer[ i + 1] - 32;  // to upper case
          }
          else{
            buffer[i] = buffer[i + 1];
          }
        }  
      }
      int i = 1;
      char suffixFound = 0;
      while ((i < bufferSize) && (! suffixFound)){
        if ((buffer[i] == lastChar1) || (buffer[i] == lastChar2)){
          suffixFound = 1;
          buffer[i] = '\0';
        }
        i++;  
      }
      if (! suffixFound){
        buffer[bufferSize - 1] = '\0';
      }  
    }  
  }
}

unsigned char iconNameToNumber(char *name){
  if ((strcmp(name, "chanceflurries") == 0) || (strcmp(name, "chancesleet") == 0) || (strcmp(name, "chancesnow") == 0)
    || (strcmp(name, "flurries") == 0) || (strcmp(name, "sleet") == 0) || (strcmp(name, "snow") == 0)) {
    return ICON_SNOW;  
  }
  else if ((strcmp(name, "chancerain") == 0) || (strcmp(name, "chancetstorms") == 0) || (strcmp(name, "rain") == 0)
     || (strcmp(name, "tstorms") == 0)){
    return ICON_RAIN;
  }
  else if ((strcmp(name, "clear") == 0) || (strcmp(name, "hazy") == 0) || (strcmp(name, "sunny") == 0)){
    return ICON_SUN;  
  }
  else if ((strcmp(name, "cloudy") == 0) || (strcmp(name, "fog") == 0) || (strcmp(name, "unknown") == 0)
     || (strcmp(name, "partlycloudy") == 0)){ 
       return ICON_CLOUD;
  }
  else{
    return ICON_CLOUD_SUN;  
  }
}

Comments

Similar projects you might like

Bionic Organs/Devices/Limbs Wireless Charging

Project showcase by Lilanka Udawatta

  • 5,184 views
  • 6 comments
  • 29 respects

Wireless Remote Weather Station (without WiFi)

Project showcase by John Weers

  • 6,074 views
  • 0 comments
  • 15 respects

Wireless weather station (Arduino + ESP8266 + Thingspeak)

Project tutorial by Alin-Constantin Paun

  • 8,864 views
  • 2 comments
  • 11 respects

The Arduino PWM: Portable Wireless Metronome

Project showcase by Anthony Chan

  • 1,010 views
  • 0 comments
  • 3 respects

PS3 Controller Control Servo Wireless

Project tutorial by Youssef Sabaa

  • 20,398 views
  • 2 comments
  • 12 respects
Add projectSign up / Login