#include <U8x8lib.h>
#include <string.h>
#include <avr/wdt.h>
#include <avr/sleep.h>
//Can use u8x8.print(F("")); to reduce RAM usage
#define testbit(data,bitno) ((data>>bitno)&0x001) //Bitwise manipulation macros
#define bit_set(var,bitno) ((var) |= 1 << (bitno))
#define bit_clr(var,bitno) ((var) &= ~(1 << (bitno)))
//clk,data,cs,dc,reset//
//U8X8_SSD1306_128X64_NONAME_4W_SW_SPI u8x8(4,5,6,7,8);
//U8X8_SSD1306_128X64_NONAME_4W_HW_SPI u8x8(6,7,8); //D11 - data, D13 - clk (bug, display wont turn on after waking)
//U8X8_SSD1306_128X64_NONAME_HW_I2C u8x8(/* reset=*/ U8X8_PIN_NONE); // OLED SSD1306 u8x8.setFlipMode(0);
U8X8_SH1106_128X64_NONAME_HW_I2C u8x8(/* reset=*/ U8X8_PIN_NONE); // OLED SSD1306 chino u8x8.setFlipMode(0);
//U8X8_SH1107_64X128_HW_I2C u8x8(/*reset=*/ U8X8_PIN_NONE); // OLED SSD1107 ; rota pantalla u8x8.setFlipMode(1);
unsigned int BAUD=9600;
unsigned int power_timeout=25000;
unsigned int power_count=0;
bool sleep_flg=0;
#define BTN A3 //User+Power Button
#define SPKR 10
#define OP 12
const uint8_t EightBall_0[32] = {0x00,0x00,0x00,0xC0,0x20,0x10,0x08,0x08,
0x04,0x02,0x02,0x02,0x01,0x01,0x01,0x01,
0x01,0x01,0x01,0x01,0x02,0x02,0x02,0x04,
0x08,0x08,0x10,0x20,0xC0,0x00,0x00,0x00};
const uint8_t EightBall_1[32] = {0xE0,0x1E,0x01,0x00,0x00,0x00,0x00,0x00,
0x00,0xC0,0xF0,0xF8,0xFC,0x9C,0x6E,0x6E,
0x6E,0x6E,0x9C,0xFC,0xF8,0xF0,0xC0,0x00,
0x00,0x00,0x00,0x00,0x00,0x01,0x1E,0xE0};
const uint8_t EightBall_2[32] = {0x07,0x78,0x80,0x00,0x00,0x00,0x00,0x00,
0x00,0x03,0x0F,0x1F,0x3F,0x38,0x77,0x77,
0x77,0x77,0x38,0x3F,0x1F,0x0F,0x03,0x00,
0x00,0x00,0x00,0x00,0x00,0x80,0x78,0x07};
const uint8_t EightBall_3[32] = {0x00,0x00,0x00,0x03,0x04,0x08,0x10,0x10,
0x20,0x40,0x40,0x40,0x80,0x80,0x80,0x80,
0x80,0x80,0x80,0x80,0x40,0x40,0x40,0x20,
0x10,0x10,0x08,0x04,0x03,0x00,0x00,0x00};
const uint8_t logo_0[32] = {0x00,0x80,0x80,0xE0,0xE0,0x18,0x18,0x1E,0x1E,0x18,0x18,0x1E,0x1E,
0x18,0x18,0x1E,0x1E,0x18,0x18,0x9E,0x9E,0x98,0x98,0x9E,0x9E,0x18,
0x18,0xE0,0xE0,0x80,0x80,0x00};
const uint8_t logo_1[32] = {0x00,0x99,0x99,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0xFE,0xFE,
0x86,0x86,0x86,0x86,0x86,0x86,0x9F,0x9F,0x19,0x19,0x1F,0x1F,0x00,
0x00,0xFF,0xFF,0x99,0x99,0x00};
const uint8_t logo_2[32] = {0x00,0x99,0x99,0xFF,0xFF,0x00,0x00,0xF8,0xF8,0x98,0x98,0xF9,0xF9,
0x61,0x61,0x61,0x61,0x61,0x61,0x7F,0x7F,0x00,0x00,0x00,0x00,0x00,
0x00,0xFF,0xFF,0x99,0x99,0x00};
const uint8_t logo_3[32] = {0x00,0x01,0x01,0x07,0x07,0x18,0x18,0x79,0x79,0x19,0x19,0x79,0x79,
0x18,0x18,0x78,0x78,0x18,0x18,0x78,0x78,0x18,0x18,0x78,0x78,0x18,
0x18,0x07,0x07,0x01,0x01,0x00};
const uint8_t Hand_0[16] = {0xC0,0x40,0x20,0x10,0x08,0x08,0x04,0x22,
0x32,0x2C,0x20,0x20,0x20,0x20,0x20,0xC0};
const uint8_t Hand_1[16] = {0x3F,0x20,0x20,0x55,0x55,0x95,0x95,0x80,
0x80,0xA9,0x069,0x1F,0x01,0x01,0x01,0x00};
const char FONT5x7[] PROGMEM ={0b00000000,0b00000000,0b00000000,0b00000000,0b00000000, // ' '
0b00000000,0b00000000,0b01011111,0b00000000,0b00000000, // !
0b00000000,0b00000111,0b00000000,0b00000111,0b00000000, // "
0b00010100,0b01111111,0b00010100,0b01111111,0b00010100, // #
0b00100100,0b00101010,0b01111111,0b00101010,0b00010010, // $
0b00100011,0b00010011,0b00001000,0b01100100,0b01100010, // %
0b00110110,0b01001001,0b01010101,0b00100010,0b01010000, // &
0b00000000,0b00000101,0b00000011,0b00000000,0b00000000, // '
0b00000000,0b00011100,0b00100010,0b01000001,0b00000000, // (
0b00000000,0b01000001,0b00100010,0b00011100,0b00000000, // )
0b00010100,0b00001000,0b00111110,0b00001000,0b00010100, // *
0b00001000,0b00001000,0b00111110,0b00001000,0b00001000, // +
0b00000000,0b01010000,0b00110000,0b00000000,0b00000000, // ,
0b00001000,0b00001000,0b00001000,0b00001000,0b00001000, // -
0b00000000,0b01100000,0b01100000,0b00000000,0b00000000, // .
0b01000000,0b00100000,0b00010000,0b00001000,0b00000100, // /
0b00111110,0b01010001,0b01001001,0b01000101,0b00111110, //0
0b00000000,0b01000010,0b01111111,0b01000000,0b00000000, //1
0b01000010,0b01100001,0b01010001,0b01001001,0b01000110, //2
0b00100010,0b01001001,0b01001001,0b01001001,0b00110110, //3
0b00011000,0b00010100,0b00010010,0b01111111,0b00010000, //4
0b00100111,0b01000101,0b01000101,0b01000101,0b00111001, //5
0b00111110,0b01001001,0b01001001,0b01001001,0b00110010, //6
0b00000001,0b00000001,0b01110001,0b00001001,0b00000111, //7
0b00110110,0b01001001,0b01001001,0b01001001,0b00110110, //8
0b00100110,0b01001001,0b01001001,0b01001001,0b00111110, //9
0b00000000,0b00110110,0b00110110,0b00000000,0b00000000, // :
0b00000000,0b01010110,0b00110110,0b00000000,0b00000000, // ;
0b00001000,0b00010100,0b00100010,0b01000001,0b00000000, // <
0b00010100,0b00010100,0b00010100,0b00010100,0b00010100, // =
0b01000001,0b00100010,0b00010100,0b00001000,0b00000000, // >
0b00000010,0b00000001,0b01010001,0b00001001,0b00000110, // ?
0b00110010,0b01001001,0b01111001,0b01000001,0b00111110, // @
0b01111100,0b00010010,0b00010001,0b00010010,0b01111100, //A
0b01111111,0b01001001,0b01001001,0b01001001,0b00110110, //B
0b00111110,0b01000001,0b01000001,0b01000001,0b00100010, //C
0b01111111,0b01000001,0b01000001,0b01000001,0b00111110, //D
0b01111111,0b01001001,0b01001001,0b01001001,0b01000001, //E
0b01111111,0b00001001,0b00001001,0b00001001,0b00000001, //F
0b00111110,0b01000001,0b01001001,0b01001001,0b01111010, //G
0b01111111,0b00001000,0b00001000,0b00001000,0b01111111, //H
0b00000000,0b01000001,0b01111111,0b01000001,0b00000000, //I
0b00100000,0b01000001,0b01000001,0b00111111,0b00000001, //J
0b01111111,0b00001000,0b00010100,0b00100010,0b01000001, //K
0b01111111,0b01000000,0b01000000,0b01000000,0b01000000, //L
0b01111111,0b00000010,0b00001100,0b00000010,0b01111111, //M
0b01111111,0b00000100,0b00001000,0b00010000,0b01111111, //N
0b00111110,0b01000001,0b01000001,0b01000001,0b00111110, //O
0b01111111,0b00001001,0b00001001,0b00001001,0b00000110, //P
0b00111110,0b01000001,0b01010001,0b00100001,0b01011110, //Q
0b01111111,0b00001001,0b00011001,0b00101001,0b01000110, //R
0b00100110,0b01001001,0b01001001,0b01001001,0b00110010, //S
0b00000001,0b00000001,0b01111111,0b00000001,0b00000001, //T
0b00111111,0b01000000,0b01000000,0b01000000,0b00111111, //U
0b00011111,0b00100000,0b01000000,0b00100000,0b00011111, //V
0b00111111,0b01000000,0b00111000,0b01000000,0b00111111, //W
0b01100011,0b00010100,0b00001000,0b00010100,0b01100011, //X
0b00000111,0b00001000,0b01110000,0b00001000,0b00000111, //Y
0b01100001,0b01010001,0b01001001,0b01000101,0b01000011, //Z
0b00000000,0b01111111,0b01000001,0b01000001,0b00000000, // [
0b00010101,0b00010110,0b01111100,0b00010110,0b00010101, // Yen
0b00000000,0b01000001,0b01000001,0b01111111,0b00000000, // ]
0b00000100,0b00000010,0b00000001,0b00000010,0b00000100, // ^
0b01000000,0b01000000,0b01000000,0b01000000,0b01000000, // _
0b00000000,0b00000001,0b00000010,0b00000100,0b00000000, // `
0b00100000,0b01010100,0b01010100,0b01010100,0b01111000, //a
0b01111111,0b01001000,0b01000100,0b01000100,0b00111000, //b
0b00111000,0b01000100,0b01000100,0b01000100,0b00100000, //c
0b00111000,0b01000100,0b01000100,0b01001000,0b01111111, //d
0b00111000,0b01010100,0b01010100,0b01010100,0b00011000, //e
0b00001000,0b01111110,0b00001001,0b00000001,0b00000010, //f
0b00001100,0b01010010,0b01010010,0b01010010,0b00111110, //g
0b01111111,0b00001000,0b00000100,0b00000100,0b01111000, //h
0b00000000,0b01000100,0b01111101,0b01000000,0b00000000, //i
0b00100000,0b01000000,0b01000100,0b00111101,0b00000000, //j
0b01111111,0b00010000,0b00101000,0b01000100,0b00000000, //k
0b00000000,0b01000001,0b01111111,0b01000000,0b00000000, //l
0b01111100,0b00000100,0b00011000,0b00000100,0b01111000, //m
0b01111100,0b00001000,0b00000100,0b00000100,0b01111000, //n
0b00111000,0b01000100,0b01000100,0b01000100,0b00111000, //o
0b01111100,0b00010100,0b00010100,0b00010100,0b00001000, //p
0b00001000,0b00010100,0b00010100,0b00011000,0b01111100, //q
0b01111100,0b00001000,0b00000100,0b00000100,0b00001000, //r
0b01001000,0b01010100,0b01010100,0b01010100,0b00100100, //s
0b00000100,0b00111111,0b01000100,0b01000000,0b00100000, //t
0b00111100,0b01000000,0b01000000,0b00100000,0b01111100, //u
0b00011100,0b00100000,0b01000000,0b00100000,0b00011100, //v
0b00111100,0b01000000,0b00111000,0b01000000,0b00111100, //w
0b01000100,0b00101000,0b00010000,0b00101000,0b01000100, //x
0b00001100,0b01010000,0b01010000,0b01010000,0b00111100, //y
0b01000100,0b01100100,0b01010100,0b01001100,0b01000100, //z
0b00000000,0b00001000,0b00110110,0b01000001,0b00000000, // {
0b00000000,0b00000000,0b01111111,0b00000000,0b00000000, // |
0b00000000,0b01000001,0b00110110,0b00001000,0b00000000, // }
0b00001000,0b00001000,0b00101010,0b00011100,0b00001000, // ->
0b00001000,0b00011100,0b00101010,0b00001000,0b00001000, // <-
};
unsigned char LineBuff[128];
unsigned char displine=1;
// " "
String Messages[]={"Es cierto",
"Esta decidido",
"Sin duda",
"Si, definitivamen",
"Puede confiar el",
"A mi modo de ver, sí",
"Lo mas probable",
"Perspectiva Buena",
"Si",
"Todo apunta que si",
"El futuro es gris",
"Pregunta mas tarde",
"Mejor no decidir",
"No decidir ahora",
"Pregunte de nuevo",
"No cuentes ello",
"Mi respuesta es no",
"Mis fuentes dicen no",
"no tan buenas",
"Muy dudoso",
};
void printchar(int x, char ASCII){
for(int i=0;i<5;i++){
LineBuff[x+i]=pgm_read_byte_near(FONT5x7+5*(ASCII-32)+i);
}
}
void writeString(int x, int y, String str){
bool chr=0;
int t=0;
unsigned char len = str.length();
unsigned char p;
while(len-20*t>0){
for(int i=0;i<20;i++){ //must make sure str is less than 20 characters long
p=str.charAt(i+20*t);
if(p==0){i=20;}else{printchar(x+i*(chr+5), p);}
chr=1;
}
u8x8.drawTile(0,y+t,16,LineBuff);
for(int i=0;i<128;i++){LineBuff[i]=0;}
t++;
//Serial.println(t);
}
//Serial.println("A");
}
void begin(void){
u8x8.begin();
}
void setContrast(int a){
u8x8.setContrast(a);
}
void clear(void){
u8x8.clear();
}
void drawTile(int a,int b,int c,int d){
u8x8.drawTile(a,b,c,d);
}
void drawString(int a,int b,int c){
u8x8.drawString(a,b,c);
}
void setFont(int a){
u8x8.setFont(a);
}
void setInverseFont(int a){
u8x8.setInverseFont(a);
}
void setPowerSave(int a){
u8x8.setPowerSave(a);
}
void setup() {
//Serial.begin(BAUD);
//Serial.println("Hello");
pinMode(BTN,INPUT_PULLUP);
pinMode(OP,OUTPUT);
digitalWrite(OP,HIGH);
pinMode(SPKR,OUTPUT);
begin();
setPowerSave(0);
setContrast(255);
setFont(u8x8_font_victoriabold8_r);
//setFont(u8x8_font_5x7_f);
u8x8.setFlipMode(0);
//u8x8.inverse();
clear();
splashscreen();
beep(3000,25);
delay(5000);
clear();
drawString(2,0,"Magic 8 Ball");
}
void tile_animate(int row,int x,bool j){
unsigned char c=0;
u8x8.clearLine(row);
for(int i=0;i<24;i++){
if(i>=x%8&&c<16){
if(j==1){
LineBuff[i]=Hand_1[c];
}else{
LineBuff[i]=Hand_0[c];
}
c++;
}
}
drawTile(x/8,row,3,LineBuff);
for(int i=0;i<24;i++){LineBuff[i]=0;}
}
void splashscreen(void){
clear();
writeString(50,2,"Magic 8 Ball");
writeString(50,3,"v1.0");
writeString(50,4,"sjm4306");
writeString(50,5,"2020");
drawTile(1,2,4,logo_0);
drawTile(1,3,4,logo_1);
drawTile(1,4,4,logo_2);
drawTile(1,5,4,logo_3);
}
void beep(unsigned int f, unsigned int len){ //Blocking beep function: f Hertz, len ms
unsigned long temp1= ((double) len * (double) f) / 1000;
unsigned int temp= (double) 500000/ (double) f;
while(temp1>0){
//Digital 10 = PB2
PORTB|=0b00000100;
//digitalWrite(SPKR,HIGH);
delayMicroseconds(temp);
PORTB&=0b11111011;
//digitalWrite(SPKR,LOW);
delayMicroseconds(temp);
temp1--;
}
}
void pinInterrupt(void){
detachInterrupt(0);
}
void loop() {
bool flash=0;
bool dir=0;
unsigned int cnt=20;
while(digitalRead(BTN)){ //Bloqueo de giro, esperando a que se presione el botón
if(cnt<10){
cnt++;
}else{
cnt=0;
flash^=1;
if(flash==1){
writeString(35,3,"Pulsar Boton");
writeString(35,4,"Para Agitar");
}else{
u8x8.clearLine(3);
u8x8.clearLine(4);
//writeString(35,3," ");
//writeString(35,4," ");
}
drawTile(0,2,4,EightBall_0);
drawTile(0,3,4,EightBall_1);
drawTile(0,4,4,EightBall_2);
drawTile(0,5,4,EightBall_3);
}
unsigned char t=0;
if(flash==1){t=50+cnt;}else{t=60-cnt;}
tile_animate(6,t,0);
tile_animate(7,t,1);
delay(50);
if(power_count>power_timeout){
sleep_flg=1;
//Serial.println("Sleeping!");
power_count=0;
delay(1000);
}else{
sleep_flg=0;
power_count++;
}
if(sleep_flg==1){
attachInterrupt(0,pinInterrupt,LOW);
set_sleep_mode(SLEEP_MODE_PWR_DOWN);
setPowerSave(1);
digitalWrite(OP,LOW);
for(int i=0;i<18;i++){
if(i!=2){digitalWrite(i,LOW);pinMode(i,INPUT);}
}
//sleep_bod_disable();
wdt_disable(); //disable watchdog
ADCSRA &= ~(1<<7); //ADEN=0, turn off adc
PRR=0b01101111; //power down individual peripherals to lower current consumption
MCUCR |= (3<<5); //set both BODS and BODSE at the same time
MCUCR = (MCUCR & ~(1<<5))|(1<<6); //then set BODS bit and clear BODSE bit at the same time
sleep_enable();
sleep_mode();
sleep_disable();
PRR=0b00000000;
setPowerSave(0);
sleep_flg=0;
//Serial.println("Awake!");
pinMode(SPKR,OUTPUT);
begin();
drawString(2,0,"Magic 8 Ball");
delay(500);
}
}
power_count=0;
u8x8.clearLine(2);
u8x8.clearLine(3);
u8x8.clearLine(4);
u8x8.clearLine(5);
u8x8.clearLine(6);
u8x8.clearLine(7);
unsigned long c=0;
unsigned char randNumber=0;
while(!digitalRead(BTN)){ //Count while button is held
c++;
writeString(35,4,"Consulting");
writeString(35,5,"Spirits");
drawTile(0,c%3+2,4,EightBall_0);
drawTile(0,c%3+3,4,EightBall_1);
drawTile(0,c%3+4,4,EightBall_2);
drawTile(0,c%3+5,4,EightBall_3);
u8x8.clearLine(c%3+1);
u8x8.clearLine(c%3+6);
if(c%3==0){u8x8.clearLine(7);}
beep(3000,25);
delay(100);
}
for(int i=1;i<8;i++){
u8x8.clearLine(i);
}
randomSeed(c+random());
delay(1000);
randNumber=random(20); //20 messages total
u8x8.clearLine(6);
u8x8.clearLine(7);
writeString(0,7,Messages[randNumber]);
writeString(35,3,"Magic 8 Ball");
writeString(35,4,"Dice:");
drawTile(0,2,4,EightBall_0);
drawTile(0,3,4,EightBall_1);
drawTile(0,4,4,EightBall_2);
drawTile(0,5,4,EightBall_3);
delay(5000);
//u8x8.clearLine(0);
}