Raffi
Published © GPL3+

Wireless Widget

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

IntermediateShowcase (no instructions)1 hour6,978
Wireless Widget

Things used in this project

Hardware components

Arduino Mega 2560
Arduino Mega 2560
×1
Arduino Wifi Shield 101
Arduino Wifi Shield 101
×1
OLED display I2C
×1
OLED display i2C
×1
P9025AC-R-EVK – Qi 5W Receiver Prototype Kit
×1
Qi 5W Receiver Prototype Kit
IDT Qi 5W Receiver Prototype Kit
×1
Qi 5W Transmitter Prototype Kit
IDT Qi 5W Transmitter Prototype Kit
×1
P9038-R-EVK – Qi 5W Transmitter Prototype Kit
×1
5V Power supply
×1
Magnet
×1
Cardboard box
×1
Cardboard
×1
USB power supply
×1
Magnet
×8
Sheet of paper
×1
Paper sheet
×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

Raffi

2 projects • 1 follower

Comments