Zaczynamy bardziej zaawansowane projekty oparte o arduino, na początek będzie to stereofoniczny odbiornik radiowy FM z odczytem kanału RDS na wyświetlaczu LCDShield (nakładka na arduino) lub na wyświetlaczu Nokia5110
Co potrzebujemy?
- moduł ATMEGA 2560 (klon)
- wyświetlacz LCD keypad SHIELD (nakładka)
A także:
- moduł radiowy RDA5807M (cena do 10 zł)
- gniazdo jack 3.5 mm trójpolowe
https://nowyelektronik.pl/index.php?id_product=16603&controller=product
PROJEKT NUMER 2
- wyświetlacz nokia 5110 (cena do 20 zł)
https://kamami.pl/lcd-84x48/180404-modlcd1.html?search_query=nokia+5110&results=1
Do tego drugiego projektu będą potrzebne także dodatkowe elementy jak:
- 3 sztuki mikroswitchy (do sterowania opcjami radia)
https://nowyelektronik.pl/index.php?id_product=72537&controller=product
- 3 sztuki rezystora 10k
- 1 rezystor 47k
Projekt oparty o wyświetlacz nokia pokażę na samym końcu.
Schemat połączeń
Program do wgrania
#include <LiquidCrystal.h>
#include <Wire.h>
#include <radio.h>
#include <rda5807M.h>
#include <si4703.h>
#include <si4705.h>
#include <tea5767.h>
#include <RDSParser.h>
enum KEYSTATE {
KEYSTATE_NONE, KEYSTATE_SELECT, KEYSTATE_LEFT, KEYSTATE_UP, KEYSTATE_DOWN, KEYSTATE_RIGHT
} __attribute__((packed));
KEYSTATE getLCDKeypadKey();
// Define some stations available at your locations here:
// 89.40 MHz as 8940
RADIO_FREQ preset[] = {
8750,
8750,
8790,
8840,
9020,
9150, // Program 1
9230,
9300, // RMF FM
9450,
9550,
9570, // ZET
9790, // Program 1
9910, // Eska
9970, // Program 3
10220, // Katowice
10560, // Program 2
10670, // Bielsko
10760, // eM
};
int i_sidx=1; ///< Która stacja z indexu ma wystartować?
/// Wybierz jaki moduł używasz
// RADIO radio;
RDA5807M radio;
// SI4703 radio;
// SI4705 radio;
// TEA5767 radio;
RDSParser rds;
enum RADIO_STATE {
STATE_PARSECOMMAND,
STATE_PARSEINT,
STATE_EXEC
};
RADIO_STATE state;
// piny wyświelacza
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
void DisplayFrequency(RADIO_FREQ f)
{
char s[12];
radio.formatFrequency(s, sizeof(s));
lcd.setCursor(0, 0); lcd.print(s);
} // DisplayFrequency()
void DisplayServiceName(char *name)
{
size_t len = strlen(name);
lcd.setCursor(0, 1);
lcd.print(name);
while (len < 8) {
lcd.print(' ');
len++;
}
}
void DisplayTime(uint8_t hour, uint8_t minute) {
lcd.setCursor(11, 0);
if (hour < 10) lcd.print('0');
lcd.print(hour);
lcd.print(':');
if (minute < 10) lcd.print('0');
lcd.println(minute);
} // DisplayTime()
void RDS_process(uint16_t block1, uint16_t block2, uint16_t block3, uint16_t block4) {
rds.processData(block1, block2, block3, block4);
}
KEYSTATE getLCDKeypadKey() {
static unsigned long lastChange = 0;
static KEYSTATE lastKey = KEYSTATE_NONE;
unsigned long now = millis();
KEYSTATE newKey;
int v = analogRead(A0);
if (v < 100) {
newKey = KEYSTATE_RIGHT;
} else if (v < 200) {
newKey = KEYSTATE_UP;
} else if (v < 400) {
newKey = KEYSTATE_DOWN;
} else if (v < 600) {
newKey = KEYSTATE_LEFT;
} else if (v < 800) {
newKey = KEYSTATE_SELECT;
} else {
newKey = KEYSTATE_NONE;
}
if (newKey != lastKey) {
lastChange = now;
lastKey = newKey;
return (KEYSTATE_NONE);
} else if (lastChange == 0) {
return (KEYSTATE_NONE);
} if (now > lastChange + 50) {
lastChange = 0;
return (newKey);
} else {
return (KEYSTATE_NONE);
} // if
} // getLCDKeypadKey()
void setup() {
// open the Serial port
Serial.begin(57600);
Serial.println("Uruchamiam radio");
lcd.begin(16, 2);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Uruchamiam radio");
delay(1000);
lcd.clear();
radio.init();
radio.debugEnable();
radio.setBandFrequency(RADIO_BAND_FM, preset[i_sidx]);
// delay(100);
radio.setMono(false);
radio.setMute(false);
// radio.debugRegisters();
radio.setVolume(8);
Serial.write('>');
state = STATE_PARSECOMMAND;
radio.attachReceiveRDS(RDS_process);
rds.attachServicenNameCallback(DisplayServiceName);
rds.attachTimeCallback(DisplayTime);
}
void loop() {
int newPos;
unsigned long now = millis();
static unsigned long nextFreqTime = 0;
static unsigned long nextRadioInfoTime = 0;
static char command;
static int16_t value;
static RADIO_FREQ lastf = 0;
RADIO_FREQ f = 0;
char c;
KEYSTATE k = getLCDKeypadKey();
if (k == KEYSTATE_RIGHT) {
radio.seekUp(true);
} else if (k == KEYSTATE_UP) {
// increase volume
Serial.println("increase volume");
int v = radio.getVolume();
if (v < 15) radio.setVolume(++v);
} else if (k == KEYSTATE_DOWN) {
// decrease volume
int v = radio.getVolume();
if (v > 0) radio.setVolume(--v);
} else if (k == KEYSTATE_LEFT) {
radio.seekDown(true);
} else if (k == KEYSTATE_SELECT) {
// 10110
radio.setFrequency(10110);
} else {
//
}
radio.checkRDS();
if (now > nextFreqTime) {
f = radio.getFrequency();
if (f != lastf) {
// print current tuned frequency
DisplayFrequency(f);
lastf = f;
}
nextFreqTime = now + 400;
}
}
Gotowy efekt:
Radio na wyświetlaczu Nokia 5110
Schemat połączeń
Program do wgrania
#include <Wire.h>
#define DEBUG 0
const int entrada = A0;
int entradaV = 0;
int menu;
#define MAXmenu 5
int menux;
#define MAXmenux 5
static char* menuS[]= {" ","MANUAL TUNE","VOLUME ","AUTO TUNE","INFO ","BASS BOST"};
int volumen=2,volumenOld=7;
int frecuencia,frecuenciaOld;
int bassbost;
unsigned int z,z1;
byte xfrecu,xfrecuOld;
unsigned int estado[6];
unsigned long time,time1,time2,time3;
// int RDA5807_adrs=0x10; // I2C-Address RDA Chip for sequential Access
// int RDA5807_adrr=0x11; // I2C-Address RDA Chip for random Access
// int RDA5807_adrt=0x60; // I2C-Address RDA Chip for TEA5767like Access
char buffer[30];
unsigned int RDS[4];
char seg_RDS[8];
char seg_RDS1[64];
char indexRDS1;
char hora,minuto,grupo,versio;
unsigned long julian;
int mezcla;
void setup()
{
Wire.begin();
Serial.begin(9600);
LcdInitialise();
LcdClear();
//drawBox();
WriteReg(0x02,0xC00D); // write 0xC00d into Reg.2 ( soft reset, enable,RDS, )
WriteReg(0x05,0x84d8); // write ,0x84d8 into Reg.3
// frecuencia inicial
frecuencia=177; //104.7
// frecuencia=26; //89.6
time3=time2=time1=time = millis();
menu=3;
canal(frecuencia);
clearRDS;
}
void loop() {
entradaV = analogRead(entrada);
#if DEBUG
Serial.print("sensor = " ); Serial.println(entradaV);delay(50);
#endif
// Boton menu
if(entradaV>500 && entradaV<524)
{
menu++;
if(menu>MAXmenu)menu=1;
Visualizar();
// sprintf(buffer,"Menu->%s",menuS[menu]); gotoXY(2,2); LcdString(buffer);
#if DEBUG
Serial.print("menu = " ); Serial.println(menu);
#endif
while(1020>analogRead(entrada))delay(5);
}
// Boton derecho
if( entradaV<50)
{
menux++;
if(menux>MAXmenux)menux=MAXmenux;
#if DEBUG
Serial.print("menux = " ); Serial.println(menux);
#endif
switch(menu)
{
case 1:
frecuencia++;
if(frecuencia>205)frecuencia=205; // верхняя граница частот
delay(130);
break;
case 2:
volumen++;
if(volumen>15)volumen=15;
while(1020>analogRead(entrada))delay(5);
break;
case 3:
busqueda(0);
while(1020>analogRead(entrada))delay(5);
break;
case 4:
LcdClear();
visualPI();
delay(3000);
LcdClear();
frecuenciaOld=-1;
break;
case 5:
bassbost++;
if(bassbost++)WriteReg(0x02,0xD00D);
while(1020>analogRead(entrada))delay(5);
break;
}
}
// Boton izquierdo
if( entradaV<700 && entradaV>660)
{
menux--;
if(menux<1)menux=1;
#if DEBUG
Serial.print("menux = " ); Serial.println(menux);
#endif
switch(menu)
{
case 1:
frecuencia--;
if(frecuencia<0)frecuencia=0;
delay(130);
break;
case 2:
volumen--;
if(volumen<0)volumen=0;
while(1020>analogRead(entrada))delay(5);
break;
case 3:
busqueda(1);
while(1020>analogRead(entrada))delay(5);
break;
case 4:
LcdClear();
visualPTY();
delay(3000);
LcdClear();
frecuenciaOld=-1;
break;
case 5:
bassbost--;
if(bassbost<0)WriteReg(0x02,0xC00D);
while(1020>analogRead(entrada))delay(5);
break;
}
}
if( millis()-time2>50)
{
ReadEstado();
time1 = millis();
//RDS
if ((estado[0] & 0x8000)!=0) {get_RDS();}
}
if( millis()-time3>500)
{
time3 = millis();
Visualizar();
}
if( frecuencia!=frecuenciaOld)
{
frecuenciaOld=frecuencia;
z=870+frecuencia;
#if DEBUG
Serial.print("Frecuencia = " ); Serial.println(frecuencia);
#endif
sprintf(buffer,"%04d ",z);
gotoXY(1,3);
for(z=0;z<5;z++)
{
if(z==3) LcdStringX(".");
LcdCharacterX(buffer[z]);
}
gotoXY(62,3);
LcdString("MHz");
canal(frecuencia);
clearRDS();
}
//Cambio de volumen
if(volumen!=volumenOld)
{
volumenOld=volumen;
sprintf(buffer,"Vol %02d",volumen); gotoXY(38,1); LcdString(buffer);
WriteReg(5, 0x84D0 | volumen);
}
}
void visualPI(void)
{
#if DEBUG
Serial.print("PAIS: "); Serial.println(RDS[0]>>12 & 0X000F);
Serial.print("Cobertura:"); Serial.println(RDS[0]>>8 & 0X000F);
Serial.print("CODIGO:"); Serial.println(RDS[0] & 0X00FF);
#endif
gotoXY(1,3);sprintf(buffer,"PAIS -%02d",RDS[0]>>12 & 0X000F); LcdString(buffer);
gotoXY(1,4);sprintf(buffer,"COBERT-%02d",RDS[0]>>8 & 0X000F); LcdString(buffer);
gotoXY(1,5);sprintf(buffer,"CODIGO-%02d",RDS[0] & 0X00FF); LcdString(buffer);
}
void visualPTY(void)
{
#if DEBUG
Serial.print("PTY: "); Serial.println(RDS[1]>>5 & 0X001F);
#endif
gotoXY(1,3); LcdString("TIPO");
gotoXY(1,4); LcdString("PROGRAMA");
gotoXY(1,5);sprintf(buffer,"%02d",RDS[1]>>5 & 0X001F); LcdString(buffer);
}
void busqueda(byte direc)
{
byte i;
if(!direc) WriteReg(0x02,0xC30d); else WriteReg(0x02,0xC10d);
for(i=0;i<10;i++)
{
delay(200);
ReadEstado();
if(estado[0]&0x4000)
{
//Serial.println("Emisora encontrada");
frecuencia=estado[0] & 0x03ff;
break;
}
}
}
void clearRDS(void)
{
gotoXY(10,4); for (z=0;z<8;z++) {seg_RDS[z]=32; LcdCharacter(32);} //borrar Name LCD Emisora
gotoXY(38,2); for (z=0;z<6;z++) { LcdCharacter(32);} //borrar linea Hora
for (z=0;z<64;z++) seg_RDS1[z]=32;
}
void Visualizar(void)
{
//Serial.print("READ_Frecuencia= " ); Serial.println(estado[0] & 0x03ff);
gotoXY(2,0); LcdStringX("FM");
sprintf(buffer,"%s",menuS[menu]); gotoXY(2,2); LcdString(buffer);
//Detectar señal stereo
gotoXY(72,0);
if((estado[0] & 0x0400)==0) LcdCharacter(32); else LcdCharacter(127);
//Señal
z=estado[1]>>10; sprintf(buffer,"S-%02d",z); gotoXY(38,0); LcdString(buffer);
sprintf(buffer,"Vol %02d",volumen); gotoXY(38,1); LcdString(buffer);
//ver RADIO_TXT
gotoXY(0,5);
z1=indexRDS1;
for (z=0;z<12;z++)
{
LcdCharacter(seg_RDS1[z1]);
z1++;
if(z1>35)z1=0;
}
indexRDS1++; if(indexRDS1>35) indexRDS1=0;
frecuencia=estado[0] & 0x03ff;
}
void canal( int canal)
{
byte numeroH,numeroL;
numeroH= canal>>2;
numeroL = ((canal&3)<<6 | 0x10);
Wire.beginTransmission(0x11);
Wire.write(0x03);
Wire.write(numeroH); // write frequency into bits 15:6, set tune bit
Wire.write(numeroL);
Wire.endTransmission();
}
//________________________
//RDA5807_adrr=0x11;
// I2C-Address RDA Chip for random Access
void WriteReg(byte reg,unsigned int valor)
{
Wire.beginTransmission(0x11);
Wire.write(reg); Wire.write(valor >> 8); Wire.write(valor & 0xFF);
Wire.endTransmission();
//delay(50);
}
//RDA5807_adrs=0x10;
// I2C-Address RDA Chip for sequential Access
int ReadEstado()
{
Wire.requestFrom(0x10, 12);
for (int i=0; i<6; i++) { estado[i] = 256*Wire.read ()+Wire.read(); }
Wire.endTransmission();
}
//READ RDS Direccion 0x11 for random access
void ReadW()
{
Wire.beginTransmission(0x11); // Device 0x11 for random access
Wire.write(0x0C); // Start at Register 0x0C
Wire.endTransmission(0); // restart condition
Wire.requestFrom(0x11,8, 1); // Retransmit device address with READ, followed by 8 bytes
for (int i=0; i<4; i++) {RDS[i]=256*Wire.read()+Wire.read();} // Read Data into Array of Unsigned Ints
Wire.endTransmission();
}
void get_RDS()
{
int i;
ReadW();
grupo=(RDS[1]>>12)&0xf;
if(RDS[1]&0x0800) versio=1; else versio=0; //Version A=0 Version B=1
if(versio==0)
{
#if DEBUG
sprintf(buffer,"Version=%d Grupo=%02d ",versio,grupo); Serial.print(buffer);
// Serial.print(" 0->");Serial.print(RDS[0],HEX);Serial.print(" 1->");Serial.print(RDS[1],HEX);Serial.print(" 2->");Serial.print(RDS[2],HEX);Serial.print(" 3->");Serial.println(RDS[03],HEX);
// Serial.print(" 0->");Serial.print(RDS[0],BIN);Serial.print(" 1->");Serial.print(RDS[1],BIN);Serial.print(" 2->");Serial.print(RDS[2],BIN);Serial.print(" 3->");Serial.println(RDS[03],BIN);
#endif
switch(grupo)
{
case 0:
#if DEBUG
Serial.print("_RDS0__");
#endif
i=(RDS[1] & 3) <<1;
seg_RDS[i]=(RDS[3]>>8);
seg_RDS[i+1]=(RDS[3]&0xFF);
gotoXY(10,4);
for (i=0;i<8;i++)
{
#if DEBUG
Serial.write(seg_RDS[i]);
#endif
if(seg_RDS[i]>31 && seg_RDS[i]<128)
LcdCharacter(seg_RDS[i]);
else
LcdCharacter(32);
}
//Serial.print("FrecuAlt1-");Serial.println((RDS[2]>>8)+875);
//Serial.print("FrecuAlt2-"); Serial.println(RDS[2]&0xFF+875);
#if DEBUG
Serial.println("---");
#endif
break;
case 2:
i=(RDS[1] & 15) <<2;
seg_RDS1[i]=(RDS[2]>>8);
seg_RDS1[i+1]=(RDS[2]&0xFF);
seg_RDS1[i+2]=(RDS[3]>>8);
seg_RDS1[i+3]=(RDS[3]&0xFF);
#if DEBUG
Serial.println("_RADIOTEXTO_");
//Serial.print(i);Serial.print(" ");Serial.println(RDS[1] & 15);
//Serial.write(RDS[2]>>8); Serial.write (RDS[2]&0xFF);Serial.write(RDS[3]>>8);Serial.write(RDS[3]&0xFF);Serial.write("_");
for (i=0;i<32;i++) Serial.write(seg_RDS1[i]);
Serial.println("-TXT-");
#endif
break;
case 4:
i=RDS[3]& 0x003f;
minuto=(RDS[3]>>6)& 0x003f;
hora=(RDS[3]>>12)& 0x000f;
if(RDS[2]&1) hora+=16;
hora+=i;
z=RDS[2]>>1;
julian=z;
if(RDS[1]&1) julian+=32768;
if(RDS[1]&2) julian+=65536;
#if DEBUG
Serial.print("_DATE_");
Serial.print(" Juliano=");Serial.print(julian);
sprintf(buffer," %02d:%02d ",hora,minuto); gotoXY(38,2); LcdString(buffer);
Serial.println(buffer);
#endif
break;
default:
#if DEBUG
Serial.println("__");
#endif
;
}
}
}
// The pins to use on the arduino
#define PIN_SCE 3
#define PIN_RESET 4
#define PIN_DC 5
#define PIN_SDIN 6
#define PIN_SCLK 7
// COnfiguration for the LCD
#define LCD_C LOW
#define LCD_D HIGH
#define LCD_CMD 0
// Size of the LCD
#define LCD_X 84
#define LCD_Y 48
int scrollPosition = -10;
static const byte ASCII[][5] =
{
{0x00, 0x00, 0x00, 0x00, 0x00} // 20
,{0x00, 0x00, 0x5f, 0x00, 0x00} // 21 !
,{0x00, 0x07, 0x00, 0x07, 0x00} // 22 "
,{0x14, 0x7f, 0x14, 0x7f, 0x14} // 23 #
,{0x24, 0x2a, 0x7f, 0x2a, 0x12} // 24 $
,{0x23, 0x13, 0x08, 0x64, 0x62} // 25 %
,{0x36, 0x49, 0x55, 0x22, 0x50} // 26 &
,{0x00, 0x05, 0x03, 0x00, 0x00} // 27 '
,{0x00, 0x1c, 0x22, 0x41, 0x00} // 28 (
,{0x00, 0x41, 0x22, 0x1c, 0x00} // 29 )
,{0x14, 0x08, 0x3e, 0x08, 0x14} // 2a *
,{0x08, 0x08, 0x3e, 0x08, 0x08} // 2b +
,{0x00, 0x50, 0x30, 0x00, 0x00} // 2c ,
,{0x08, 0x08, 0x08, 0x08, 0x08} // 2d -
,{0x00, 0x60, 0x60, 0x00, 0x00} // 2e .
,{0x20, 0x10, 0x08, 0x04, 0x02} // 2f /
,{0x3e, 0x51, 0x49, 0x45, 0x3e} // 30 0
,{0x00, 0x42, 0x7f, 0x40, 0x00} // 31 1
,{0x42, 0x61, 0x51, 0x49, 0x46} // 32 2
,{0x21, 0x41, 0x45, 0x4b, 0x31} // 33 3
,{0x18, 0x14, 0x12, 0x7f, 0x10} // 34 4
,{0x27, 0x45, 0x45, 0x45, 0x39} // 35 5
,{0x3c, 0x4a, 0x49, 0x49, 0x30} // 36 6
,{0x01, 0x71, 0x09, 0x05, 0x03} // 37 7
,{0x36, 0x49, 0x49, 0x49, 0x36} // 38 8
,{0x06, 0x49, 0x49, 0x29, 0x1e} // 39 9
,{0x00, 0x36, 0x36, 0x00, 0x00} // 3a :
,{0x00, 0x56, 0x36, 0x00, 0x00} // 3b ;
,{0x08, 0x14, 0x22, 0x41, 0x00} // 3c <
,{0x14, 0x14, 0x14, 0x14, 0x14} // 3d =
,{0x00, 0x41, 0x22, 0x14, 0x08} // 3e >
,{0x02, 0x01, 0x51, 0x09, 0x06} // 3f ?
,{0x32, 0x49, 0x79, 0x41, 0x3e} // 40 @
,{0x7e, 0x11, 0x11, 0x11, 0x7e} // 41 A
,{0x7f, 0x49, 0x49, 0x49, 0x36} // 42 B
,{0x3e, 0x41, 0x41, 0x41, 0x22} // 43 C
,{0x7f, 0x41, 0x41, 0x22, 0x1c} // 44 D
,{0x7f, 0x49, 0x49, 0x49, 0x41} // 45 E
,{0x7f, 0x09, 0x09, 0x09, 0x01} // 46 F
,{0x3e, 0x41, 0x49, 0x49, 0x7a} // 47 G
,{0x7f, 0x08, 0x08, 0x08, 0x7f} // 48 H
,{0x00, 0x41, 0x7f, 0x41, 0x00} // 49 I
,{0x20, 0x40, 0x41, 0x3f, 0x01} // 4a J
,{0x7f, 0x08, 0x14, 0x22, 0x41} // 4b K
,{0x7f, 0x40, 0x40, 0x40, 0x40} // 4c L
,{0x7f, 0x02, 0x0c, 0x02, 0x7f} // 4d M
,{0x7f, 0x04, 0x08, 0x10, 0x7f} // 4e N
,{0x3e, 0x41, 0x41, 0x41, 0x3e} // 4f O
,{0x7f, 0x09, 0x09, 0x09, 0x06} // 50 P
,{0x3e, 0x41, 0x51, 0x21, 0x5e} // 51 Q
,{0x7f, 0x09, 0x19, 0x29, 0x46} // 52 R
,{0x46, 0x49, 0x49, 0x49, 0x31} // 53 S
,{0x01, 0x01, 0x7f, 0x01, 0x01} // 54 T
,{0x3f, 0x40, 0x40, 0x40, 0x3f} // 55 U
,{0x1f, 0x20, 0x40, 0x20, 0x1f} // 56 V
,{0x3f, 0x40, 0x38, 0x40, 0x3f} // 57 W
,{0x63, 0x14, 0x08, 0x14, 0x63} // 58 X
,{0x07, 0x08, 0x70, 0x08, 0x07} // 59 Y
,{0x61, 0x51, 0x49, 0x45, 0x43} // 5a Z
,{0x00, 0x7f, 0x41, 0x41, 0x00} // 5b [
,{0x02, 0x04, 0x08, 0x10, 0x20} // 5c ¥
,{0x00, 0x41, 0x41, 0x7f, 0x00} // 5d ]
,{0x04, 0x02, 0x01, 0x02, 0x04} // 5e ^
,{0x40, 0x40, 0x40, 0x40, 0x40} // 5f _
,{0x00, 0x01, 0x02, 0x04, 0x00} // 60 `
,{0x20, 0x54, 0x54, 0x54, 0x78} // 61 a
,{0x7f, 0x48, 0x44, 0x44, 0x38} // 62 b
,{0x38, 0x44, 0x44, 0x44, 0x20} // 63 c
,{0x38, 0x44, 0x44, 0x48, 0x7f} // 64 d
,{0x38, 0x54, 0x54, 0x54, 0x18} // 65 e
,{0x08, 0x7e, 0x09, 0x01, 0x02} // 66 f
,{0x0c, 0x52, 0x52, 0x52, 0x3e} // 67 g
,{0x7f, 0x08, 0x04, 0x04, 0x78} // 68 h
,{0x00, 0x44, 0x7d, 0x40, 0x00} // 69 i
,{0x20, 0x40, 0x44, 0x3d, 0x00} // 6a j
,{0x7f, 0x10, 0x28, 0x44, 0x00} // 6b k
,{0x00, 0x41, 0x7f, 0x40, 0x00} // 6c l
,{0x7c, 0x04, 0x18, 0x04, 0x78} // 6d m
,{0x7c, 0x08, 0x04, 0x04, 0x78} // 6e n
,{0x38, 0x44, 0x44, 0x44, 0x38} // 6f o
,{0x7c, 0x14, 0x14, 0x14, 0x08} // 70 p
,{0x08, 0x14, 0x14, 0x18, 0x7c} // 71 q
,{0x7c, 0x08, 0x04, 0x04, 0x08} // 72 r
,{0x48, 0x54, 0x54, 0x54, 0x20} // 73 s
,{0x04, 0x3f, 0x44, 0x40, 0x20} // 74 t
,{0x3c, 0x40, 0x40, 0x20, 0x7c} // 75 u
,{0x1c, 0x20, 0x40, 0x20, 0x1c} // 76 v
,{0x3c, 0x40, 0x30, 0x40, 0x3c} // 77 w
,{0x44, 0x28, 0x10, 0x28, 0x44} // 78 x
,{0x0c, 0x50, 0x50, 0x50, 0x3c} // 79 y
,{0x44, 0x64, 0x54, 0x4c, 0x44} // 7a z
,{0x00, 0x08, 0x36, 0x41, 0x00} // 7b {
,{0x00, 0x00, 0x7f, 0x00, 0x00} // 7c |
,{0x00, 0x41, 0x36, 0x08, 0x00} // 7d }
,{0x10, 0x08, 0x08, 0x10, 0x08} // 7e ←
//,{0x00, 0x06, 0x09, 0x09, 0x06} // 7f →
,{B11111111, B01111110, B00011000, B01111110, B11111111} //Stereo 127
};
void LcdCharacter(char character)
{
unsigned char z,z1;
z1=character - 0x20;
LcdWrite(LCD_D, 0x00);
for (int index = 0; index < 5; index++)
{
//para que funciona en proteus
z=ASCII[z1][index];
LcdWrite(LCD_D, z);
// LcdWrite(LCD_D, ASCII[character - 0x20][index]);
}
LcdWrite(LCD_D, 0x00);
}
void LcdCharacterX(char character)
{
unsigned char z,z1;
z1=character - 0x20;
LcdWrite(LCD_D, 0x00);
for (int index = 0; index < 5; index++)
{
//para que funciona en proteus
z=ASCII[z1][index];
LcdWrite(LCD_D, z);
LcdWrite(LCD_D, z);
//LcdWrite(LCD_D, ASCII[character - 0x20][index]);
//LcdWrite(LCD_D, ASCII[character - 0x20][index]);
}
LcdWrite(LCD_D, 0x00);
}
void LcdClear(void)
{
for (int index = 0; index < LCD_X * LCD_Y / 8; index++)
{
LcdWrite(LCD_D, 0x00);
}
}
void LcdInitialise(void)
{
pinMode(PIN_SCE, OUTPUT);
pinMode(PIN_RESET, OUTPUT);
pinMode(PIN_DC, OUTPUT);
pinMode(PIN_SDIN, OUTPUT);
pinMode(PIN_SCLK, OUTPUT);
digitalWrite(PIN_RESET, LOW);
digitalWrite(PIN_RESET, HIGH);
LcdWrite(LCD_CMD, 0x21); // LCD Extended Commands.
LcdWrite(LCD_CMD, 0xB5); // Set LCD Vop (Contrast). //B1
LcdWrite(LCD_CMD, 0x04); // Set Temp coefficent. //0x04
LcdWrite(LCD_CMD, 0x14); // LCD bias mode 1:48. //0x13
LcdWrite(LCD_CMD, 0x0C); // LCD in normal mode. 0x0d for inverse
LcdWrite(LCD_C, 0x20);
LcdWrite(LCD_C, 0x0C);
}
void LcdString(char *characters)
{
while (*characters)
{
LcdCharacter(*characters++);
}
}
void LcdStringX(char *characters)
{
while (*characters)
{
LcdCharacterX(*characters++);
}
}
void LcdWrite(byte dc, byte data)
{
digitalWrite(PIN_DC, dc);
digitalWrite(PIN_SCE, LOW);
shiftOut(PIN_SDIN, PIN_SCLK, MSBFIRST, data);
digitalWrite(PIN_SCE, HIGH);
}
/**
* gotoXY routine to position cursor
* x - range: 0 to 84
* y - range: 0 to 5
*/
void gotoXY(int x, int y)
{
LcdWrite( 0, 0x80 | x); // Column.
LcdWrite( 0, 0x40 | y); // Row.
}
void drawBox(void)
{
int j;
for(j = 0; j < 84; j++) // top
{
gotoXY(j, 0);
LcdWrite(1, 0x01);
}
for(j = 0; j < 84; j++) //Bottom
{
gotoXY(j, 5);
LcdWrite(1, 0x80);
}
for(j = 0; j < 6; j++) // Right
{
gotoXY(83, j);
LcdWrite(1, 0xff);
}
for(j = 0; j < 6; j++) // Left
{
gotoXY(0, j);
LcdWrite(1, 0xff);
}
}
void Scroll(String message)
{
for (int i = scrollPosition; i < scrollPosition + 11; i++)
{
if ((i >= message.length()) || (i < 0))
{
LcdCharacter(' ');
}
else {
LcdCharacter(message.charAt(i));
}
}
scrollPosition++;
if ((scrollPosition >= message.length()) && (scrollPosition > 0))
{
scrollPosition = -10;
}
}
Gotowy efekt:
Sketche oraz biblioteki do pobrania:
https://drive.google.com/open?id=1Gq162uteS3eq0CjgH9kvE4JMffXJfxPo