Hello everyone,
I am new to the forum so thank you in advance for the assistance here.
I am getting back into programming with arduino and built a POV fidget spinner inspired by an instructable by MakersBox. I am using the SparkFun AVR Pocket Programmer and an ATTiny84 (8MHz internal clock). The code is a bit over my head and I am still working on understanding it. The project uses persistence of vision to display images using 8 LEDs on a custom fidget spinner PCB. The font.h and textAndShapes.h header files (both shown below) store pre-built arrays with the sequence of bytes which turn the 8 LEDs on and off in just the right manner to display shapes and text. I have two questions below.
1. Is anyone able to explain to me how the bytes are actually output to the LEDs in the code? I am not able to figure out where or how that is done.
2. I am getting the below error while compiling and cannot sort out what is going on. It seems that there is an issue with the Serial set of commands. I have included the error below.
c:\Users\Franklin Marquette\Documents\Arduino\libraries\EEPROMEx\EEPROMex.cpp: In member function 'void EEPROMClassEx::setMemPool(int, int)':
c:\Users\Franklin Marquette\Documents\Arduino\libraries\EEPROMEx\EEPROMex.cpp:63:3: error: 'Serial' was not declared in this scope
Serial.println("Cannot change base, addresses have been issued");
^~~~~~
c:\Users\Franklin Marquette\Documents\Arduino\libraries\EEPROMEx\EEPROMex.cpp:63:3: note: suggested alternative: 'Stream'
Serial.println("Cannot change base, addresses have been issued");
^~~~~~
Stream
c:\Users\Franklin Marquette\Documents\Arduino\libraries\EEPROMEx\EEPROMex.cpp:66:3: error: 'Serial' was not declared in this scope
Serial.println("Cannot change ceiling, below issued addresses");
^~~~~~
c:\Users\Franklin Marquette\Documents\Arduino\libraries\EEPROMEx\EEPROMex.cpp:66:3: note: suggested alternative: 'Stream'
Serial.println("Cannot change ceiling, below issued addresses");
^~~~~~
Stream
c:\Users\Franklin Marquette\Documents\Arduino\libraries\EEPROMEx\EEPROMex.cpp: In member function 'int EEPROMClassEx::getAddress(int)':
c:\Users\Franklin Marquette\Documents\Arduino\libraries\EEPROMEx\EEPROMex.cpp:89:3: error: 'Serial' was not declared in this scope
Serial.println("Attempt to write outside of EEPROM memory");
^~~~~~
c:\Users\Franklin Marquette\Documents\Arduino\libraries\EEPROMEx\EEPROMex.cpp:89:3: note: suggested alternative: 'Stream'
Serial.println("Attempt to write outside of EEPROM memory");
^~~~~~
Stream
c:\Users\Franklin Marquette\Documents\Arduino\libraries\EEPROMEx\EEPROMex.cpp: In member function 'bool EEPROMClassEx::isWriteOk(int)':
c:\Users\Franklin Marquette\Documents\Arduino\libraries\EEPROMEx\EEPROMex.cpp:324:3: error: 'Serial' was not declared in this scope
Serial.println("Exceeded maximum number of writes");
^~~~~~
c:\Users\Franklin Marquette\Documents\Arduino\libraries\EEPROMEx\EEPROMex.cpp:324:3: note: suggested alternative: 'Stream'
Serial.println("Exceeded maximum number of writes");
^~~~~~
Stream
c:\Users\Franklin Marquette\Documents\Arduino\libraries\EEPROMEx\EEPROMex.cpp:329:3: error: 'Serial' was not declared in this scope
Serial.println("Attempt to write outside of EEPROM memory");
^~~~~~
c:\Users\Franklin Marquette\Documents\Arduino\libraries\EEPROMEx\EEPROMex.cpp:329:3: note: suggested alternative: 'Stream'
Serial.println("Attempt to write outside of EEPROM memory");
^~~~~~
Stream
c:\Users\Franklin Marquette\Documents\Arduino\libraries\EEPROMEx\EEPROMex.cpp: In member function 'bool EEPROMClassEx::isReadOk(int)':
c:\Users\Franklin Marquette\Documents\Arduino\libraries\EEPROMEx\EEPROMex.cpp:345:3: error: 'Serial' was not declared in this scope
Serial.println("Attempt to write outside of EEPROM memory");
^~~~~~
c:\Users\Franklin Marquette\Documents\Arduino\libraries\EEPROMEx\EEPROMex.cpp:345:3: note: suggested alternative: 'Stream'
Serial.println("Attempt to write outside of EEPROM memory");
^~~~~~
Stream
exit status 1
Compilation error: exit status 1
font.h Header File:
///============================================================
// Arduino Bike POV
// font.h
//
// by Scott Mitchell
// www.openobject.org
// Open Source Urbanism
//
// Copyright (C) 2008 Scott Mitchell 12-10-2008
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// A copy of the GNU General Public License
// can be found at <http://www.gnu.org/licenses/>.
//
// B4.1
// Last Modified: October 13, 2008
//============================================================
// defining the alphabet
// ascii 7x5 side-feeding characters for led modules
// adapted from http://www.sxlist.com/TECHREF/datafile/charset/8x6.htm
// Modified to place data in program memory to save dynamic memory
// https://playground.arduino.cc/Main/PROGMEM
// http://www.gammon.com.au/progmem
const char PROGMEM font1[95][5] = {
{//
0b00000000,
0b00000000,
0b00000000,
0b00000000,
0b00000000 },
{// !
0b00000000,
0b00000000,
0b11110110,
0b00000000,
0b00000000 },
{// "
0b00000000,
0b11100000,
0b00000000,
0b11100000,
0b00000000 },
{// #
0b00101000,
0b11111110,
0b00101000,
0b11111110,
0b00101000 },
{// $
0b00000000,
0b11100000,
0b00100000,
0b01111000,
0b00000000 },
{// %
0b11000100,
0b11001000,
0b00010000,
0b00100110,
0b01000110 },
{// &
0b01101100,
0b10010010,
0b01101010,
0b00000100,
0b00001010 },
{// '
0b00000000,
0b00000000,
0b11100000,
0b00000000,
0b00000000 },
{// (
0b00000000,
0b00111000,
0b01000100,
0b10000010,
0b00000000 },
{// )
0b00000000,
0b10000010,
0b01000100,
0b00111000,
0b00000000 },
{// *
0b00101000,
0b00010000,
0b01111100,
0b00010000,
0b00101000 },
{// +
0b00010000,
0b00010000,
0b01111100,
0b00010000,
0b00010000 },
{// ,
0b00000000,
0b00001010,
0b00001100,
0b00000000,
0b00000000 },
{// -
0b00010000,
0b00010000,
0b00010000,
0b00010000,
0b00010000 },
{// .
0b00000000,
0b00000110,
0b00000110,
0b00000000,
0b00000000 },
{// /
0b00000100,
0b00001000,
0b00010000,
0b00100000,
0b01000000 },
{// 0
0b01111100,
0b10001010,
0b10010010,
0b10100010,
0b01111100 },
{// 1
0b00000000,
0b01000010,
0b11111110,
0b00000010,
0b00000000 },
{// 2
0b01000010,
0b10000110,
0b10001010,
0b10010010,
0b01100010 },
{// 3
0b10000100,
0b10000010,
0b10100010,
0b11010010,
0b10001100 },
{// 4
0b00011000,
0b00101000,
0b01001000,
0b11111110,
0b00001000 },
{// 5
0b11100100,
0b10100010,
0b10100010,
0b10100010,
0b10011100 },
{// 6
0b00111100,
0b01010010,
0b10010010,
0b10010010,
0b00001100 },
{// 7
0b10000000,
0b10001110,
0b10010000,
0b10100000,
0b11000000 },
{// 8
0b01101100,
0b10010010,
0b10010010,
0b10010010,
0b01101100 },
{// 9
0b01100000,
0b10010010,
0b10010010,
0b10010100,
0b01111000 },
{// :
0b00000000,
0b01101100,
0b01101100,
0b00000000,
0b00000000 },
{// ;
0b00000000,
0b01101010,
0b01101100,
0b00000000,
0b00000000 },
{// <
0b00010000,
0b00101000,
0b01000100,
0b10000010,
0b00000000 },
{// =
0b00101000,
0b00101000,
0b00101000,
0b00101000,
0b00101000 },
{// >
0b00000000,
0b10000010,
0b01000100,
0b00101000,
0b00010000 },
{// ?
0b01000000,
0b10000000,
0b10001010,
0b10010000,
0b01100000 },
{// @
0b01111100,
0b10000010,
0b10111010,
0b10010010,
0b01110010 },
{// A
0b01111110,
0b10010000,
0b10010000,
0b10010000,
0b01111110 },
{// B
0b11111110,
0b10010010,
0b10010010,
0b10010010,
0b01101100 },
{// C
0b01111100,
0b10000010,
0b10000010,
0b10000010,
0b01000100 },
{// D
0b11111110,
0b10000010,
0b10000010,
0b10000010,
0b01111100 },
{// E
0b11111110,
0b10010010,
0b10010010,
0b10010010,
0b10000010 },
{// F
0b11111110,
0b10010000,
0b10010000,
0b10010000,
0b10000000 },
{// G
0b01111100,
0b10000010,
0b10010010,
0b10010010,
0b01011110 },
{// H
0b11111110,
0b00010000,
0b00010000,
0b00010000,
0b11111110 },
{// I
0b00000000,
0b10000010,
0b11111110,
0b10000010,
0b00000000 },
{// J
0b00000100,
0b00000010,
0b10000010,
0b11111100,
0b10000000 },
{// K
0b11111110,
0b00010000,
0b00101000,
0b01000100,
0b10000010 },
{// L
0b11111110,
0b00000010,
0b00000010,
0b00000010,
0b00000010 },
{// M
0b11111110,
0b01000000,
0b00110000,
0b01000000,
0b11111110 },
{// N
0b11111110,
0b00100000,
0b00010000,
0b00001000,
0b11111110 },
{// O
0b01111100,
0b10000010,
0b10000010,
0b10000010,
0b01111100 },
{// P
0b11111110,
0b10010000,
0b10010000,
0b10010000,
0b01100000 },
{// Q
0b01111100,
0b10000010,
0b10001010,
0b10000100,
0b01111010 },
{// R
0b11111110,
0b10010000,
0b10011000,
0b10010100,
0b01100010 },
{// S
0b01100010,
0b10010010,
0b10010010,
0b10010010,
0b10001100 },
{// T
0b10000000,
0b10000000,
0b11111110,
0b10000000,
0b10000000 },
{// U
0b11111100,
0b00000010,
0b00000010,
0b00000010,
0b11111100 },
{// V
0b11110000,
0b00001100,
0b00000010,
0b00001100,
0b11110000 },
{// W
0b11111100,
0b00000010,
0b00001100,
0b00000010,
0b11111100 },
{// X
0b11000110,
0b00101000,
0b00010000,
0b00101000,
0b11000110 },
{// Y
0b11100000,
0b00010000,
0b00001110,
0b00010000,
0b11100000 },
{// Z
0b10000110,
0b10001010,
0b10010010,
0b10100010,
0b11000010 },
{// [
0b00111100,
0b01010010,
0b10010010,
0b10010100,
0b01111000 },
{// \
0b01000000,
0b00100000,
0b00010000,
0b00001000,
0b00000100 },
{// ]
0b00000000,
0b10000010,
0b11111110,
0b00000000,
0b00000000 },
{// ^
0b00100000,
0b01000000,
0b10000000,
0b01000000,
0b00100000 },
{// _
0b00000010,
0b00000010,
0b00000010,
0b00000010,
0b00000010 },
{// `
0b00000000,
0b00000000,
0b11000000,
0b00100000,
0b00000000 },
{// a
0b00000100,
0b00101010,
0b00101010,
0b00101010,
0b00011110 },
{// b
0b11111110,
0b00010010,
0b00100010,
0b00100010,
0b00011100 },
{// c
0b00011100,
0b00100010,
0b00100010,
0b00100010,
0b00000100 },
{// d
0b00011100,
0b00100010,
0b00100010,
0b00010010,
0b11111110 },
{// e
0b00011100,
0b00101010,
0b00101010,
0b00101010,
0b00011000 },
{// f
0b00010000,
0b01111110,
0b10010000,
0b10000000,
0b01000000 },
{// g
0b00110000,
0b01001010,
0b01001010,
0b01001010,
0b01111100 },
{// h
0b11111110,
0b00010000,
0b00100000,
0b00100000,
0b00011110 },
{// i
0b00000000,
0b00100010,
0b10111110,
0b00000010,
0b00000000 },
{// j
0b00000100,
0b00000010,
0b00100010,
0b10111100,
0b00000000 },
{// k
0b00000000,
0b11111110,
0b00001000,
0b00010100,
0b00100010 },
{// l
0b00000000,
0b10000010,
0b11111110,
0b00000010,
0b00000000 },
{// m
0b00111110,
0b00100000,
0b00011000,
0b00100000,
0b00011110 },
{// n
0b00111110,
0b00010000,
0b00100000,
0b00100000,
0b00011110 },
{// o
0b00011100,
0b00100010,
0b00100010,
0b00100010,
0b00011100 },
{// p
0b00111110,
0b00101000,
0b00101000,
0b00101000,
0b00010000 },
{// q
0b00010000,
0b00101000,
0b00101000,
0b00011000,
0b00111110 },
{// r
0b00111110,
0b00010000,
0b00100000,
0b00100000,
0b00010000 },
{// s
0b00010010,
0b00101010,
0b00101010,
0b00101010,
0b00000100 },
{// t
0b00100000,
0b11111100,
0b00100010,
0b00000010,
0b00000100 },
{// u
0b00111100,
0b00000010,
0b00000010,
0b00000100,
0b00111110 },
{// v
0b00111000,
0b00000100,
0b00000010,
0b00000100,
0b00111000 },
{// w
0b00111100,
0b00000010,
0b00001100,
0b00000010,
0b00111100 },
{// x
0b00100010,
0b00010100,
0b00001000,
0b00010100,
0b00100010 },
{// y
0b00110000,
0b00001010,
0b00001010,
0b00001010,
0b00111100 },
{// z
0b00100010,
0b00100110,
0b00101010,
0b00110010,
0b00100010 },
{// {
0b00000000,
0b00010000,
0b01101100,
0b10000010,
0b10000010 },
{// |
0b00000000,
0b00000000,
0b11111110,
0b00000000,
0b00000000 },
{// }
0b10000010,
0b10000010,
0b01101100,
0b00010000,
0b00000000 },
{// ~
0b00100000,
0b01000000,
0b00100000,
0b00010000,
0b00100000 }
};
const char PROGMEM font[95][5] = {
{0x00,0x00,0x00,0x00,0x00}, // 0x20 32
{0x00,0x00,0x6f,0x00,0x00}, // ! 0x21 33
{0x00,0x07,0x00,0x07,0x00}, // " 0x22 34
{0x14,0x7f,0x14,0x7f,0x14}, // # 0x23 35
{0x00,0x07,0x04,0x1e,0x00}, // $ 0x24 36
{0x23,0x13,0x08,0x64,0x62}, // % 0x25 37
{0x36,0x49,0x56,0x20,0x50}, // & 0x26 38
{0x00,0x00,0x07,0x00,0x00}, // ' 0x27 39
{0x00,0x1c,0x22,0x41,0x00}, // ( 0x28 40
{0x00,0x41,0x22,0x1c,0x00}, // ) 0x29 41
{0x14,0x08,0x3e,0x08,0x14}, // * 0x2a 42
{0x08,0x08,0x3e,0x08,0x08}, // + 0x2b 43
{0x00,0x50,0x30,0x00,0x00}, // , 0x2c 44
{0x08,0x08,0x08,0x08,0x08}, // - 0x2d 45
{0x00,0x60,0x60,0x00,0x00}, // . 0x2e 46
{0x20,0x10,0x08,0x04,0x02}, // / 0x2f 47
{0x3e,0x51,0x49,0x45,0x3e}, // 0 0x30 48
{0x00,0x42,0x7f,0x40,0x00}, // 1 0x31 49
{0x42,0x61,0x51,0x49,0x46}, // 2 0x32 50
{0x21,0x41,0x45,0x4b,0x31}, // 3 0x33 51
{0x18,0x14,0x12,0x7f,0x10}, // 4 0x34 52
{0x27,0x45,0x45,0x45,0x39}, // 5 0x35 53
{0x3c,0x4a,0x49,0x49,0x30}, // 6 0x36 54
{0x01,0x71,0x09,0x05,0x03}, // 7 0x37 55
{0x36,0x49,0x49,0x49,0x36}, // 8 0x38 56
{0x06,0x49,0x49,0x29,0x1e}, // 9 0x39 57
{0x00,0x36,0x36,0x00,0x00}, // : 0x3a 58
{0x00,0x56,0x36,0x00,0x00}, // ; 0x3b 59
{0x08,0x14,0x22,0x41,0x00}, // < 0x3c 60
{0x14,0x14,0x14,0x14,0x14}, // = 0x3d 61
{0x00,0x41,0x22,0x14,0x08}, // > 0x3e 62
{0x02,0x01,0x51,0x09,0x06}, // ? 0x3f 63
{0x3e,0x41,0x5d,0x49,0x4e}, // @ 0x40 64
{0x7e,0x09,0x09,0x09,0x7e}, // A 0x41 65
{0x7f,0x49,0x49,0x49,0x36}, // B 0x42 66
{0x3e,0x41,0x41,0x41,0x22}, // C 0x43 67
{0x7f,0x41,0x41,0x41,0x3e}, // D 0x44 68
{0x7f,0x49,0x49,0x49,0x41}, // E 0x45 69
{0x7f,0x09,0x09,0x09,0x01}, // F 0x46 70
{0x3e,0x41,0x49,0x49,0x7a}, // G 0x47 71
{0x7f,0x08,0x08,0x08,0x7f}, // H 0x48 72
{0x00,0x41,0x7f,0x41,0x00}, // I 0x49 73
{0x20,0x40,0x41,0x3f,0x01}, // J 0x4a 74
{0x7f,0x08,0x14,0x22,0x41}, // K 0x4b 75
{0x7f,0x40,0x40,0x40,0x40}, // L 0x4c 76
{0x7f,0x02,0x0c,0x02,0x7f}, // M 0x4d 77
{0x7f,0x04,0x08,0x10,0x7f}, // N 0x4e 78
{0x3e,0x41,0x41,0x41,0x3e}, // O 0x4f 79
{0x7f,0x09,0x09,0x09,0x06}, // P 0x50 80
{0x3e,0x41,0x51,0x21,0x5e}, // Q 0x51 81
{0x7f,0x09,0x19,0x29,0x46}, // R 0x52 82
{0x46,0x49,0x49,0x49,0x31}, // S 0x53 83
{0x01,0x01,0x7f,0x01,0x01}, // T 0x54 84
{0x3f,0x40,0x40,0x40,0x3f}, // U 0x55 85
{0x0f,0x30,0x40,0x30,0x0f}, // V 0x56 86
{0x3f,0x40,0x30,0x40,0x3f}, // W 0x57 87
{0x63,0x14,0x08,0x14,0x63}, // X 0x58 88
{0x07,0x08,0x70,0x08,0x07}, // Y 0x59 89
{0x61,0x51,0x49,0x45,0x43}, // Z 0x5a 90
{0x3c,0x4a,0x49,0x29,0x1e}, // [ 0x5b 91
{0x02,0x04,0x08,0x10,0x20}, // \ 0x5c 92
{0x00,0x41,0x7f,0x00,0x00}, // ] 0x5d 93
{0x04,0x02,0x01,0x02,0x04}, // ^ 0x5e 94
{0x40,0x40,0x40,0x40,0x40}, // _ 0x5f 95
{0x00,0x00,0x03,0x04,0x00}, // ` 0x60 96
{0x20,0x54,0x54,0x54,0x78}, // a 0x61 97
{0x7f,0x48,0x44,0x44,0x38}, // b 0x62 98
{0x38,0x44,0x44,0x44,0x20}, // c 0x63 99
{0x38,0x44,0x44,0x48,0x7f}, // d 0x64 100
{0x38,0x54,0x54,0x54,0x18}, // e 0x65 101
{0x08,0x7e,0x09,0x01,0x02}, // f 0x66 102
{0x0c,0x52,0x52,0x52,0x3e}, // g 0x67 103
{0x7f,0x08,0x04,0x04,0x78}, // h 0x68 104
{0x00,0x44,0x7d,0x40,0x00}, // i 0x69 105
{0x20,0x40,0x44,0x3d,0x00}, // j 0x6a 106
{0x00,0x7f,0x10,0x28,0x44}, // k 0x6b 107
{0x00,0x41,0x7f,0x40,0x00}, // l 0x6c 108
{0x7c,0x04,0x18,0x04,0x78}, // m 0x6d 109
{0x7c,0x08,0x04,0x04,0x78}, // n 0x6e 110
{0x38,0x44,0x44,0x44,0x38}, // o 0x6f 111
{0x7c,0x14,0x14,0x14,0x08}, // p 0x70 112
{0x08,0x14,0x14,0x18,0x7c}, // q 0x71 113
{0x7c,0x08,0x04,0x04,0x08}, // r 0x72 114
{0x48,0x54,0x54,0x54,0x20}, // s 0x73 115
{0x04,0x3f,0x44,0x40,0x20}, // t 0x74 116
{0x3c,0x40,0x40,0x20,0x7c}, // u 0x75 117
{0x1c,0x20,0x40,0x20,0x1c}, // v 0x76 118
{0x3c,0x40,0x30,0x40,0x3c}, // w 0x77 119
{0x44,0x28,0x10,0x28,0x44}, // x 0x78 120
{0x0c,0x50,0x50,0x50,0x3c}, // y 0x79 121
{0x44,0x64,0x54,0x4c,0x44}, // z 0x7a 122
{0x00,0x08,0x36,0x41,0x41}, // { 0x7b 123
{0x00,0x00,0x7f,0x00,0x00}, // | 0x7c 124
{0x41,0x41,0x36,0x08,0x00}, // } 0x7d 125
{0x04,0x02,0x04,0x08,0x04}, // ~ 0x7e 126
};
/*
Creative Commons Attribution-Noncommercial-Share Alike 2.5 Australia License
This page was last modified 14:41, 11 January 2009. This page has been accessed 1,477 times.
Content is available under Creative Commons Attribution-Noncommercial-Share Alike 2.5 Australia License.
About Open Source Urbanism
Disclaimers
Powered by MediaWiki
*/
textAndShapes Header File:
// Place data (except text[]) in program memory to save dynamic memory
// https://playground.arduino.cc/Main/PROGMEM
// http://www.gammon.com.au/progmem
const char text[] = "Hello";
const char string_0[] PROGMEM = "World";
const char string_1[] PROGMEM = " RPM";
const char string_2[] PROGMEM = " SEC";
const char string_3[] PROGMEM = " REV";
const char string_4[] PROGMEM = " odo";
const char * const string_table[] PROGMEM = { // change "string_table" name to suit
string_0,
string_1,
string_2,
string_3,
string_4,
};
const char PROGMEM shape_1[] = { // heart
B10000000,
B01000000,
B01000000,
B00100000,
B00100000,
B00100000,
B00010000,
B00010000,
B00010000,
B00010000,
B00010000,
B00010000,
B00010000,
B00010000,
B00010000,
B00010000,
B00010000,
B00100000,
B00100000,
B00100000,
B00100000,
B01000000,
B01000000,
B01000000,
B10000000,
B10000000,
B10000000,
B10000000,
B10000000,
B01000000,
B00100000,
B00010000,
B00001000,
B00000100,
B00000010,
B00000001,
B00000001,
B00000010,
B00000100,
B00001000,
B00010000,
B00100000,
B01000000,
B10000000,
B10000000,
B10000000,
B10000000,
B10000000,
B01000000,
B01000000,
B01000000,
B00100000,
B00100000,
B00100000,
B00100000,
B00010000,
B00010000,
B00010000,
B00010000,
B00010000,
B00010000,
B00010000,
B00010000,
B00010000,
B00010000,
B00010000,
B00100000,
B00100000,
B00100000,
B01000000,
B01000000,
B10000000,
};
const char PROGMEM shape_SIGMA[] = {
B00000100,
B00000110,
B00000110,
B00000110,
B00000110,
B00000110,
B00000110,
B00000110,
B00000110,
B00000110,
B00000110,
B00000100,
B00000100,
B00000100,
B00000001,
B00000001,
B00000011,
B00000111,
B00001111,
B00011111,
B00111111,
B01100111,
B11000111,
B10000111,
B10000111,
B01100111,
B00010111,
B00001111,
B00000111,
B00000111,
B00000111,
B00000111,
B00000111,
B00000111,
B00000111,
B00000111,
B00000111,
B00000111,
B00000111,
B00000111,
B00000111,
B00000111,
B00000111,
B00000111,
B00000111,
B00000111,
B00000111,
B00000111,
B00000111,
B00000111,
B00000111,
B00000111,
B00000111,
B00000111,
B00000111,
B00001111,
B00110111,
B01000111,
B10000111,
B10000111,
B11000111,
B01100111,
B00111111,
B00011111,
B00001111,
B00000011,
B00000011,
B00000001,
B00000001,
B00000000,
B00000100,
B00000100,
};
const char PROGMEM shape_2[] = { // smile
B10001000,
B10001000,
B10001000,
B10001000,
B10001000,
B10001000,
B10001000,
B10001000,
B10001000,
B10001000,
B10000000,
B10000000,
B10000000,
B10000000,
B10000000,
B10000000,
B10000000,
B10000000,
B10000000,
B10000000,
B10000000,
B10000000,
B10000000,
B10000000,
B10000000,
B10001100,
B10011110,
B10011110,
B10001100,
B10000000,
B10000000,
B10000000,
B10000000,
B10000000,
B10000000,
B10000000,
B10000000,
B10000000,
B10000000,
B10000000,
B10000000,
B10000000,
B10000000,
B10001100,
B10011110,
B10011110,
B10001100,
B10000000,
B10000000,
B10000000,
B10000000,
B10000000,
B10000000,
B10000000,
B10000000,
B10000000,
B10000000,
B10000000,
B10000000,
B10000000,
B10000000,
B10000000,
B10001000,
B10001000,
B10001000,
B10001000,
B10001000,
B10001000,
B10001000,
B10001000,
B10001000,
B10001000,
};
/*
Creative Commons Attribution-Noncommercial-Share Alike 2.5 Australia License
This page was last modified 14:41, 11 January 2009. This page has been accessed 1,477 times.
Content is available under Creative Commons Attribution-Noncommercial-Share Alike 2.5 Australia License.
About Open Source Urbanism
Disclaimers
Powered by MediaWiki
*/
Code:
/*
cd C:\Users\MakersBox\Downloads\arduino-1.6.4\hardware\tools\avr\bin
avrdude -C ..\etc\avrdude.conf -P COM8 -b 19200 -c avrisp -p attiny84 -v -e -U lfuse:w:0xE2:m -U hfuse:w:0xD7:m -U efuse:w:0xFf:m -U flash:w:SMD_spinner_THT_R2b.cpp.hex
Attiny Core:
https://github.com/SpenceKonde/ATTinyCore
Board: Attiny 24/44/84
Pin Mapping: Counter-Clockwise
Chip: Attiny 84
Clock: 8 MHz (internal)
// ATMEL ATTINY84 / ARDUINO
//
// +-\/-+
// VCC 1| |14 GND
// (D 0) PB0 2| |13 AREF (D 10)
// (D 1) PB1 3| |12 PA1 (D 9)
// PB3 4| |11 PA2 (D 8)
// PWM INT0 (D 2) PB2 5| |10 PA3 (D 7)
// PWM (D 3) PA7 6| |9 PA4 (D 6)
// PWM (D 4) PA6 7| |8 PA5 (D 5) PWM
*/
#include <EEPROMex.h>
#include <avr/pgmspace.h>
#include <avr/sleep.h>
#include "font.h"
#include "textAndShapes.h"
// clear and set interup routines
#ifndef cbi
#define cbi(sfr, bit) (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit) (_SFR_BYTE(sfr) |= _BV(bit))
#endif
const int charHeight = 8;
const int charWidth = 5;
int rows= 8; // Total LED's in a row
bool STATES[] = {LOW, LOW, LOW, LOW, LOW, LOW, LOW, LOW};
int LEDS[] = {10, 9, 8, 7, 6, 5, 4, 3}; // Port A
byte magPin = 2; // Hall effect sensor, pulled-up, goes low when magnet passes
byte buttonPin = 0;
char charArray[6]; // holds characters to display
unsigned long lastTimeUs; // time (us) magnet sensed
unsigned long revTimeUs; // time (us) of last full rotation
unsigned long dwellTimeUs; // time (us) between LED changes (based on rotation speed)
volatile unsigned long revolutions = 0; // track number of revolutions since last start
long totalRevolutions; // track total number of revolutions (stored in EEPROM)
bool spinning = true; // track reset of time & counts
unsigned long startTimeUs; // time (us) current spinning started
int mode; // current operating mode, stored in EEPROM
int modes = 8; // number of modes available
// 0 -> text "Hello World!"
// 1 -> RPM
// 2 -> time in seconds
// 3 -> spin count
// 4 -> spin count (total)
// 5 -> "lilly pad" pattern
// 6 -> shape 1 (heart)
// 7 -> shape 2 (smile)
volatile boolean rotationFlag = false; // modified by ISR
void setup(){
// setup inputs
pinMode(buttonPin, INPUT_PULLUP);
//digitalWrite(buttonPin, HIGH);
pinMode(magPin, INPUT_PULLUP);
//digitalWrite(magPin, HIGH);
// setup other LEDs
for(int LED=0; LED<(sizeof(LEDS)/sizeof(int)); LED++){
pinMode(LEDS[LED], OUTPUT);
digitalWrite(LEDS[LED], STATES[LED]);
}
// Interupt setting
GIMSK = bit (PCIE1); // Pin change interrupt enable
PCMSK1 = bit (PCINT10); // Enable interupt on PCINT10 (D2)
sei(); // enables interrupts
// get saved mode from eeprom
mode = EEPROM.read(0);
if (mode >= modes) {
mode = 0; // may be very large first time
}
// get saved revolution total from eeprom
totalRevolutions = EEPROMReadlong(1);
if (totalRevolutions < 0 || totalRevolutions > 999999UL){ // will be -1 first time.
totalRevolutions = 0;
EEPROMWritelong(1, 0);
}
// show we are alive and what mode is active
blipLEDs();
lastTimeUs = micros();
}
void loop(){
int sigFigs = 5; // number of significant figures to deplay
unsigned long curTimeUs;
int seconds;
unsigned int rpm;
checkButton();
if ((micros() - lastTimeUs) > 20000000UL){ // sleep after 20 seconds
digitalWrite(LEDS[0], HIGH);
ledsOff();
system_sleep();
lastTimeUs = micros();
}
if (((micros() - lastTimeUs) > 2000000UL)){ // less than 1 rev / sec
if (spinning){
spinning = false;
totalRevolutions = totalRevolutions + revolutions;
EEPROMWritelong(1, totalRevolutions);
revolutions = 0;
clearArray();
blipLEDs();
digitalWrite(LEDS[mode], LOW);
//system_sleep();
}
else {
//digitalWrite(LEDS[mode], LOW);
}
}
if (mode == 5){ // lilly pad pattern, show regardles of magnet.
for(int LED=0; LED<(sizeof(LEDS)/sizeof(int)); LED++){
digitalWrite(LEDS[LED], HIGH);
delay(1);
digitalWrite(LEDS[LED], LOW);
}
for(int LED=(sizeof(LEDS)/sizeof(int))-1; LED >= 0; LED--){
digitalWrite(LEDS[LED], HIGH);
delay(1);
digitalWrite(LEDS[LED], LOW);
}
}
else if (rotationFlag){ // we are spinning!
rotationFlag = false;
if (!spinning){
spinning = true;
startTimeUs = micros();
}
curTimeUs = micros();
revTimeUs = curTimeUs - lastTimeUs;
dwellTimeUs = revTimeUs * 3UL / 360UL; // 3 degrees
seconds = (curTimeUs - startTimeUs) / 1000000UL;
rpm = 60000 * 1000 / revTimeUs;
lastTimeUs = curTimeUs;
clearArray();
if (mode == 0){
strcpy (charArray, text);
//sprintf(charArray, "%lu", dwellTimeUs);
}
else if (mode == 1){
sprintf(charArray, "%d", rpm);
sigFigs = 3;
}
else if (mode == 2){
sprintf(charArray, " %d", seconds);
}
else if (mode == 3){
sprintf(charArray, " %lu", revolutions);
}
else if (mode == 4){
sprintf(charArray, "%lu", totalRevolutions + revolutions);
}
else if (mode == 6 || mode ==7){ // shapes 1 or 2
dwellTimeUs = revTimeUs * 5UL / 360UL; // 5 degrees
for(int k=0; k< sizeof(shape_1);k++){
if (rotationFlag){
break;
}
int i = k + 26; // advancing because of magnet location
if(i >= sizeof(shape_1)){
i = i - sizeof(shape_1);
}
char b;
if (mode == 6){
b = pgm_read_byte_near(&(shape_1[i]));
}
else{
b = pgm_read_byte_near(&(shape_2[i]));
}
//for (int j=0; j<charHeight; j++) {
// digitalWrite(LEDS[j], bitRead(b, j));
//}
PORTA = b;
delayMicroseconds(dwellTimeUs);
}
}
// Text in top half
if (mode < 5) {
int digits = 0;
for(int k=0; k< sizeof(charArray); k++){
char c = charArray[k];
if (rotationFlag){
break;
}
if(c){
if(mode==0){
printLetter(c);
}
else{
if (digits < sigFigs){
printLetter(c);
//digits += 1;
}
else{
printLetter('0');
}
digits += 1;
}
}
}
// Handle display in lower section
clearArray();
if(1 && (revTimeUs < 200000)){
char * ptr = (char *) pgm_read_word (&string_table[mode]);
//char buffer [6]; // must be large enough!
strcpy_P (charArray, ptr);
// wait for it . . .
while((micros() < (lastTimeUs + revTimeUs / 2 - 5 * dwellTimeUs)) && !rotationFlag){};
// show it
for (int k=sizeof(charArray)-1; k>=0; k--){
if (rotationFlag){
break;
}
printLetterLower(charArray[k]);;
}
}
}
}
}
ISR(PCINT1_vect){ // Magnet sensed
if (!digitalRead(magPin)){
rotationFlag = true; // Increment volatile variables
revolutions += 1;
}
}
void ledsOff(){
for(int LED=0; LED<(sizeof(LEDS)/sizeof(int)); LED++){
digitalWrite(LEDS[LED], LOW);
}
}
void dwellDelay(){ // avoid glitch on first rotation having erronious value
if (dwellTimeUs > 2000){
dwellTimeUs = 2000;
}
if (dwellTimeUs < 100){
dwellTimeUs = 100;
}
delayMicroseconds(dwellTimeUs);
}
void printLetter(char ch){
// https://github.com/reger-men/Arduion-POV-clock/blob/master/clock.ino
// make sure the character is within the alphabet bounds (defined by the font.h file)
// if it's not, make it a blank character
if (ch < 32 || ch > 126){
ch = 32;
}
// subtract the space character (converts the ASCII number to the font index number)
ch -= 32;
// step through each byte of the character array
for (int i=0; i<charWidth; i++) {
char b = pgm_read_byte_near(&(font1[ch][i]));
//for (int j=0; j<charHeight; j++) {
// digitalWrite(LEDS[j], bitRead(b, 7-j));
//}
PORTA = b;
dwellDelay();
}
//clear the LEDs
PORTA = 0;
//for (int i = 0; i < rows; i++){
// digitalWrite(LEDS[i] , LOW);
//}
dwellDelay();
dwellDelay();
}
void printLetterLower(char ch){
// make sure the character is within the alphabet bounds (defined by the font.h file)
// if it's not, make it a blank character
if (ch < 32 || ch > 126){
ch = 32;
}
// subtract the space character (converts the ASCII number to the font index number)
ch -= 32;
// step through each byte of the character array
for (int i=charWidth-1; i>-1; i--) {
char b = pgm_read_byte_near(&(font[ch][i]))<<1;
PORTA = b;
//for (int j=0; j<charHeight; j++) {
// digitalWrite(LEDS[j+1], bitRead(b, j));
//}
dwellDelay();
}
//clear the LEDs
for (int i=0; i<rows; i++){
digitalWrite(LEDS[i], LOW);
}
//PORTA = 0;
// space between letters
dwellDelay();
dwellDelay();
}
bool touched(){
// returns true if touched, false if not. Light LED until touch released
bool touchVal = digitalRead(buttonPin);
if (!touchVal){
while(!digitalRead(buttonPin)){ // wait till touch release
delay(10);
digitalWrite(LEDS[mode], LOW);
}
//digitalWrite(LEDS[0], LOW);
return (true);
}
else{
return (false);
}
}
void checkButton(){
// check button for mode change and display current mode
if (touched()){
mode += 1;
if (mode >= modes){
mode = 0;
}
EEPROM.write(0, mode);
blipLEDs();
}
}
void blipLEDs(){
// something to show we are alive
for(int LED=0; LED<(sizeof(LEDS)/sizeof(int)); LED++){
digitalWrite(LEDS[LED], HIGH);
delay(10);
digitalWrite(LEDS[LED], LOW);
}
for(int LED=sizeof(LEDS)/sizeof(int); LED>mode; LED--){
digitalWrite(LEDS[LED], HIGH);
delay(10);
digitalWrite(LEDS[LED], LOW);
}
digitalWrite(LEDS[mode], HIGH);
}
void EEPROMWritelong(int address, long value) {
//This function will write a 4 byte (32bit) long to the eeprom at
//the specified address to address + 3.
//https://playground.arduino.cc/Code/EEPROMReadWriteLong
//Decomposition from a long to 4 bytes by using bitshift.
//One = Most significant -> Four = Least significant byte
byte four = (value & 0xFF);
byte three = ((value >> 8) & 0xFF);
byte two = ((value >> 16) & 0xFF);
byte one = ((value >> 24) & 0xFF);
//Write the 4 bytes into the eeprom memory.
EEPROM.write(address, four);
EEPROM.write(address + 1, three);
EEPROM.write(address + 2, two);
EEPROM.write(address + 3, one);
}
long EEPROMReadlong(long address){
//Read the 4 bytes from the eeprom memory.
long four = EEPROM.read(address);
long three = EEPROM.read(address + 1);
long two = EEPROM.read(address + 2);
long one = EEPROM.read(address + 3);
//Return the recomposed long by using bitshift.
return ((four << 0) & 0xFF) + ((three << 8) & 0xFFFF) + ((two << 16) & 0xFFFFFF) + ((one << 24) & 0xFFFFFFFF);
}
void clearArray(){
for(int i=0; i<sizeof(charArray); i++){ // clear array
charArray[i] = 0;
}
}
// set system into the sleep state
// system wakes up when wtchdog is timed out
void system_sleep() {
cbi(ADCSRA,ADEN); // switch Analog to Digitalconverter OFF
set_sleep_mode(SLEEP_MODE_PWR_DOWN); // sleep mode is set here
sleep_enable();
sleep_mode(); // System sleeps here
sleep_disable(); // System continues execution here when watchdog timed out
sbi(ADCSRA,ADEN); // switch Analog to Digitalconverter ON
}
Thank you so much!
Franklin