As a maker, I am always over-designing stuff. Mostly selecting Arduino nano even for simple stuff like blinking the LED. So, I decided to make a project using the minimal required hardware for this project while still not being too inconvenient to get parts or develop the project.
RequirementsSo, the requirements are simple. I need my project to blink a NeoPixel RGB led for the encoded message with the press of a button. I need the project to be battery powered and that's about it.
HardwareFor the project, I selected an ATTiny85. An 8 pin IC comes loaded with 6 GPIO, SPI, I2C interfaces. The chip can also be programmed with an Arduino bootloader and thus makes it very easy to be programmed.
For the RGB LED, the obvious choice was the infamous WS2812B. Working over a single wire interface makes it very convenient to be controlled.
For the battery charging and protection circuit, I decided to go with a prebuilt module based on TP4056. It adds acharging circuit along with overcharge, overcurrent protection for Li-Ion battery. I also added a slide switch to act as a power cut for the circuit.
For the interaction, a push button in the default pull up condition was added to an interrupt pin.
The final schematic look something like this.
After soldering the discussed circuit on the perfboard, the final hardware looked like the following.
The software written for this is based on Arduino. In order to get started with this, I needed to flash Arduino bootloader to the ATTiny85 first. Following a detailed tutorial by Arjun Ganesan at the link, it seemed pretty straightforward.
Following that, I wrote the program. It contains the following major block.
1. Declare the colors for 0, 1 and off-state
2. Declare the ASCII codes as a two-dimensional array of characters. The inner array being an 8-bit array (0 + 7-bit code) of code and the outer array encapsulating the characters
3. An external interrupt on the falling edge of the button press triggers send message function
4. Send message function loops through the string, loops through each bit of the character, and flashes the corresponding digit. It also adds a delay for space and next character.
#include <FastLED.h>
#define NUM_LEDS 1
#define DATA_PIN 1 //pin number where led is connected
CRGB leds[NUM_LEDS];
// color for various states
CRGB zeroColor = 0xFF0000; // color when one
CRGB oneColor = 0x0000FF; // color when one
CRGB offColor = 0x000000; // color when off
// ascii code for all capital letters
bool ascii[26][8] = {
{0,1,0,0,0,0,0,1},// A
{0,1,0,0,0,0,1,0},// B
{0,1,0,0,0,0,1,1},// C
{0,1,0,0,0,1,0,0},// D
{0,1,0,0,0,1,0,1},// E
{0,1,0,0,0,1,1,0},// F
{0,1,0,0,0,1,1,1},// G
{0,1,0,0,1,0,0,0},// H
{0,1,0,0,1,0,0,1},// I
{0,1,0,0,1,0,1,0},// J
{0,1,0,0,1,0,1,1},// K
{0,1,0,0,1,1,0,0},// L
{0,1,0,0,1,1,0,1},// M
{0,1,0,0,1,1,1,0},// N
{0,1,0,0,1,1,1,1},// O
{0,1,0,1,0,0,0,0},// P
{0,1,0,1,0,0,0,1},// Q
{0,1,0,1,0,0,1,0},// R
{0,1,0,1,0,0,1,1},// S
{0,1,0,1,0,1,0,0},// T
{0,1,0,1,0,1,0,1},// U
{0,1,0,1,0,1,1,0},// V
{0,1,0,1,0,1,1,1},// W
{0,1,0,1,1,0,0,0},// X
{0,1,0,1,1,0,0,1},// Y
{0,1,0,1,1,0,1,0} // Z
};
// string to send length
int strLength = 23;
// must be capital or small letters. Numbers and punctuations not allowed
char *str = "NOT ANOTHER HELLO WORLD";
// send zero
void zero(){
leds[0] = zeroColor;
FastLED.show();
delay(700);
leds[0] = offColor;
FastLED.show();
delay(300);
}
// send one
void one(){
leds[0] = oneColor;
FastLED.show();
delay(700);
leds[0] = offColor;
FastLED.show();
delay(300);
}
// delay for letter end
void nextLetter(){
leds[0] = offColor;
FastLED.show();
delay(1500);
}
// delay for space (will be called 8 times for each space hence small delay)
void space(){
leds[0] = offColor;
FastLED.show();
delay(200);
}
void setup() {
FastLED.addLeds<WS2812, DATA_PIN, GRB>(leds, NUM_LEDS);
leds[0] = offColor;
FastLED.show();
external_interrupt();
}
void loop() {
}
// loop through string and send each character
void sendMessage(){
// loop through all the letters in the string
for(int i = 0; i < strLength; i++){
char letter = str[i];
// each letter has 8 bits
for(int j = 0; j < 8; j++){
// index for capital case
if(letter >= 65 && letter <= 90){
if(ascii[letter - 65][j]){
one();
}
else{
zero();
}
}
// index for small case
else if(letter >= 97 && letter <= 122){
if(ascii[letter - 97][j]){
one();
}
else{
zero();
}
}
// else it is a space
else {
space();
}
}
// turn of led for sometime to distinguish between characters
nextLetter();
}
}
// external interrupt attached to switch
void external_interrupt()
{
DDRB |= (1<<PB1)|(1<<PB0); // set PB2 as output(LED)
sei(); //enabling global interrupt
GIMSK |= (1<<INT0); // enabling the INT0 (external interrupt)
MCUCR |= (1<<ISC01); // Configuring as falling edge
}
// interrupt service routine for interrupt
ISR (INT0_vect) // Interrupt service routine
{
sendMessage();
}
Comments