Raffi
Published © GPL3+

Wireless Widget

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

IntermediateShowcase (no instructions)1 hour7,103
Wireless Widget

Things used in this project

Hardware components

Arduino Mega
×1
Arduino Wifi Shield 101
Arduino Wifi Shield 101
×1
OLED display I2C
×1
OLED display i2C
×1
Qi 5W Receiver Prototype Kit
IDT Qi 5W Receiver Prototype Kit
×1
P9025AC-R-EVK – Qi 5W Receiver Prototype Kit
×1
P9038-R-EVK – Qi 5W Transmitter Prototype Kit
×1
Qi 5W Transmitter Prototype Kit
IDT Qi 5W Transmitter Prototype Kit
×1
Magnet
×1
5V Power supply
×1
Cardboard
×1
Cardboard box
×1
USB power supply
×1
Magnet
×8
Paper sheet
×1
Sheet of paper
×1
USB cable type B
×1

Story

Read more

Code

WirelessWidget.ino

C/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;  
  }
}

Credits

Raffi
2 projects • 1 follower

Comments