I built it from scratch, then created a PCB for better display I use a tilt switch to turn it on when the fan spins. You can change in the code, what it says, speeds and working on reverse mode (code still under construction).
/*
* ATtiny402-POV-fan.c
*
* Created: 1/31/2024 17:36:42
* Author : sherm
*/
#define F_CPU 3333333
#include <avr/io.h>
#include <util/delay.h>
#include "povFont.h"
#define led0 PIN1_bm
#define led1 PIN2_bm
#define led2 PIN3_bm
#define led3 PIN6_bm
#define led4 PIN7_bm
//#define spaceDelay 2000 //use space font 26 instead.
#define letterSpaceDelay 800
#define columnSpaceDelay 200
#define columnOnDelay 1000
const uint8_t word[]={P,R,A,Y,SPACE,O,F,T,E,N,EP,SPACE,SPACE};
void dispLetter(uint8_t);
void displayWord (void);
//not working yet
void dispLetterReverse(uint8_t);
void displayWordReverse (void);
int main(void)
{
/* Replace with your application code */
PORTA.DIRSET = PIN3_bm|PIN1_bm|PIN2_bm|PIN6_bm|PIN7_bm;
// PORTA.OUT = PIN7_bm|PIN6_bm|PIN3_bm|PIN1_bm|PIN2_bm;
while (1)
{
// displayWordReverse();
dispLetter(SPACE);
displayWord();
dispLetter(SPACE);
}
}
//not working functions///////////////////////////////////////////////////
void displayWordReverse (void){
// for(uint8_t i = sizeof(word)-1; i>=0;i--){
dispLetterReverse(P);//word[i]);
// }
/*
uint8_t revLetter=sizeof(word);
revLetter--;
do{
dispLetterReverse(sizeof word); //[revLetter]);
revLetter--;
}while(revLetter>=0);
*/
}
void dispLetterReverse(uint8_t Rletter){ //letter
uint8_t revWord;
// uint8_t revWord = 4;
// do{
// revWord--;
for (revWord=0;revWord < 5;revWord++){
if(font[Rletter][revWord] == 0){
PORTA.OUTCLR= PIN7_bm|PIN6_bm|PIN3_bm|PIN1_bm|PIN2_bm;
}else{
if(0x1 & font[Rletter][revWord]){
PORTA.OUTSET = led0;
}
if(0x2 & font[Rletter][revWord]){//revWord
PORTA.OUTSET = led1;
}
if(0x4 & font[Rletter][revWord]){
PORTA.OUTSET = led2;
}
if(0x8 & font[Rletter][revWord]){
PORTA.OUTSET = led3;
}
if(0x10 & font[Rletter][revWord]){
PORTA.OUTSET = led4;
}
}
_delay_us(columnOnDelay);
PORTA.OUTCLR= PIN7_bm|PIN6_bm|PIN3_bm|PIN1_bm|PIN2_bm;
_delay_us(columnSpaceDelay);
// revWord--;
// } while (revWord >=0);
}
PORTA.OUTCLR= PIN7_bm|PIN6_bm|PIN3_bm|PIN1_bm|PIN2_bm;
_delay_us(letterSpaceDelay);
}
//working functions//////////////////////////////////////////////////////////////
void displayWord (void){
for(uint8_t i = 0; i<sizeof(word);i++){
dispLetter(word[i]);
}
}
void dispLetter(uint8_t letter){
for (uint8_t i=0;i<5;i++){
if(font[letter][i] == 0){
PORTA.OUTCLR= PIN7_bm|PIN6_bm|PIN3_bm|PIN1_bm|PIN2_bm;
}else{
if(0x1 & font[letter][i]){
PORTA.OUTSET = led0;
}
if(0x2 & font[letter][i]){
PORTA.OUTSET = led1;
}
if(0x4 & font[letter][i]){
PORTA.OUTSET = led2;
}
if(0x8 & font[letter][i]){
PORTA.OUTSET = led3;
}
if(0x10 & font[letter][i]){
PORTA.OUTSET = led4;
}
}
_delay_us(columnOnDelay);
PORTA.OUTCLR= PIN7_bm|PIN6_bm|PIN3_bm|PIN1_bm|PIN2_bm;
_delay_us(columnSpaceDelay);
}
PORTA.OUTCLR= PIN7_bm|PIN6_bm|PIN3_bm|PIN1_bm|PIN2_bm;
_delay_us(letterSpaceDelay);
}
/*
* povFont.h
*
* Created: 2/1/2024 12:00:15
* Author: sherm
*/
#ifndef POVFONT_H_
#define POVFONT_H_
#define A 0
#define B 1
#define C 2
#define D 3
#define E 4
#define F 5
#define G 6
#define H 7
#define I 8
#define J 9
#define K 10
#define L 11
#define M 12
#define N 13
#define O 14
#define P 15
#define Q 16
#define R 17
#define S 18
#define T 19
#define U 20
#define V 21
#define W 22
#define X 23
#define Y 24
#define Z 25
#define SPACE 26
#define EP 27
#define QM 28
#define PERIOD 29
#define DASH 30
const uint8_t font[31][5] = {
{0b00011100, //A
0b00000110,
0b00000101,
0b00000110,
0b00011100},
{0b00011111, //B
0b00010101,
0b00010101,
0b00010101,
0b00001010},
{0b00001110, //C
0b00010001,
0b00010001,
0b00010001,
0b00001010},
{0b00011111, //D
0b00010001,
0b00010001,
0b00001010,
0b00000100},
{0b00011111, //E
0b00010101,
0b00010101,
0b00010101,
0b00010101},
{0b00011111, //F
0b00000101,
0b00000101,
0b00000101,
0b00000001},
{0b00001110, //G
0b00010001,
0b00010001,
0b00010101,
0b00011101},
{0b00011111, //H
0b00000100,
0b00000100,
0b00000100,
0b00011111},
{0b00000000, //I
0b00010001,
0b00011111,
0b00010001,
0b00000000},
{0b00000001, //J
0b00001001,
0b00010001,
0b00001111,
0b00000001},
{0b00011111, //K
0b00000100,
0b00001010,
0b00010001,
0b00000000},
{0b00000000, //L
0b00011111,
0b00010000,
0b00010000,
0b00000000},
{0b00011111, //M
0b00000010,
0b00000100,
0b00000010,
0b00011111},
{0b00011111, //N
0b00000010,
0b00000100,
0b00001000,
0b00011111},
{0b00001110, //O
0b00010001,
0b00010001,
0b00010001,
0b00001110},
{0b00011111, //P
0b00000101,
0b00000101,
0b00000101,
0b00000010},
{0b00001110, //Q
0b00010001,
0b00010001,
0b00001001,
0b00010110},
{0b00011111, //R
0b00000101,
0b00000101,
0b00001101,
0b00010110},
{0b00010010, //S
0b00010101,
0b00010101,
0b00001001,
0b00000000},
{0b00000001, //T
0b00000001,
0b00011111,
0b00000001,
0b00000001},
{0b00001111, //U
0b00010000,
0b00010000,
0b00010000,
0b00001111},
{0b00000111, //V
0b00001000,
0b00010000,
0b00001000,
0b00000111},
{0b00001111, //W
0b00010000,
0b00000100,
0b00010000,
0b00001111},
{0b00010001, //X
0b00001010,
0b00000100,
0b00001010,
0b00010001},
{0b00000001, //Y
0b00000010,
0b00011100,
0b00000010,
0b00000001},
{0b00010001, //Z
0b00011001,
0b00010101,
0b00010011,
0b00010001},
{0b00000000, //SPACE
0b00000000,
0b00000000,
0b00000000,
0b00000000},
{0b00000000, //EP
0b00000000,
0b00010111,
0b00000000,
0b00000000},
{0b00000000, //QM
0b00000010,
0b00011001,
0b00000101,
0b00000010},
{0b00000000, //PERIOD
0b00010000,
0b00000000,
0b00000000,
0b00000000},
{0b00000000, //DASH
0b00000100,
0b00000100,
0b00000100,
0b00000000}
};
#endif /* POVFONT_H_ */