arduino pt6961 led matrix watch
- Войдите на сайт для отправки комментариев
Вс, 19/01/2014 - 22:55
Часы с использованием старой лед матрицы от музыкального центра на PT6961, умеют показывать время, дату, температуру, влажность, давление, умеет показывать синусоиду аудиосигнала, реализован клеточный атомат.
Видео работы:http://youtu.be/EhRbLSdxsAQ
Код кому интересно(внимание много костылей мусора и прочего так как мне лень сделать красиво):
#include <SPI.h>
#include <DS1307.h>
#include <dht11.h>
#include <Wire.h>
#include <Adafruit_BMP085.h>
dht11 DHT11;
#define DHT11PIN 3
Adafruit_BMP085 bmp;
const int SSPin = 10;
const int SSPin1 = 9;
const int SSPin2 = 8;
const int bKey1 = 6;
const int key_up = 7;
const int key_dw = 2;
unsigned long previousMillis;
unsigned long prMillis;
unsigned long prMillisTD;
int vL = 0x8A;
int val = 0;
int val0=0;
int val1=0;
int val2=0;
int valH;
int valM;
int valS;
int valD;
int valMon;
int valY;
byte inv=0;
//byte dott=0;
Time t;
DS1307 rtc(4, 5);
const int myArray1[7]=
{0xc0,0xc2,0xc4,0xc6,0xc8,0xca,0xcc};
const int myArray2[11]=
{1,2,4,8,16,32,64,128,1,2,4};
//int nxt = 0;
byte r1 = 0;
byte r2 = 0;
byte myArray[7][29]={
{0,0,1,1,1,1,1,0,0,1,1,1,0,0,1,0,0,1,0,1,1,0,0,1,0,0,1,1,0},
{0,1,0,1,1,0,0,1,0,1,0,0,1,0,1,0,0,1,0,0,1,0,0,1,0,1,0,0,1},
{1,0,0,1,1,0,0,1,0,1,0,0,1,0,1,0,0,1,0,1,1,0,0,1,0,1,0,0,1},
{1,0,0,1,1,1,1,0,0,1,0,0,1,0,1,0,0,1,0,1,1,1,0,1,0,1,0,0,1},
{1,1,1,1,1,0,1,0,0,1,0,0,1,0,1,0,0,1,0,1,1,0,1,1,0,1,0,0,1},
{1,0,0,1,1,0,0,1,0,1,0,0,1,0,1,0,0,1,0,1,1,0,0,1,0,1,0,0,1},
{1,0,0,1,1,0,0,1,0,1,1,1,0,0,0,1,1,0,0,1,1,0,0,1,0,0,1,1,0},
};
byte myArrayBF[7][29];
byte myA0[7][66]={
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0},
{1,1,1,0,1,0,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,0,1,0,0,1,1,1,1,1,1,1,1,1,0,1,0,0,0,1,1,0,1,0,0,0},
{1,0,1,1,1,0,1,0,1,0,0,1,1,0,1,1,0,0,1,0,0,0,0,1,1,0,1,1,0,1,0,1,0,0,0,0,1,1,1,1,1,1,1,0,0,1,0,1,1,0,1,1,0,1,1,0,0,1,1,1,1,0,1,1,1,1},
{1,0,1,0,1,0,0,0,1,0,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,1,0,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,0,0,0,1,1,1,1,0,1},
{1,0,1,0,1,0,0,1,0,0,0,1,0,0,1,0,0,1,1,0,1,0,1,0,1,0,1,0,0,1,0,1,0,0,0,0,1,1,1,0,1,0,1,0,1,0,0,0,1,0,1,0,0,1,1,0,1,0,0,0,1,0,1,1,1,1},
{1,1,1,1,1,1,1,1,1,1,1,1,0,0,1,1,1,1,1,1,1,0,1,0,1,1,1,1,1,1,0,0,0,0,1,0,0,0,0,0,1,1,1,0,1,0,0,0,1,1,1,0,1,0,1,1,1,0,0,0,1,0,1,0,0,1},
{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1},
};
void setup() {
rtc.halt(false);
pinMode (SSPin, OUTPUT);
pinMode (SSPin1, OUTPUT);
pinMode (SSPin2, OUTPUT);
pinMode (bKey1, INPUT);
// Serial.begin(115200);
// Serial.begin(9600);
if (!bmp.begin()) {
//Serial.println("Could not find a valid BMP085 sensor, check wiring!");
while (1) {}
}
SPI.begin();// initialize SPI
//rtc.setTime(22, 02, 00); // Set the time to 12:00:00 (24hr format)
//delay(10);
SPI.setBitOrder(LSBFIRST);
SPI.setDataMode(SPI_MODE0);
initialize6961();
clearAll();
initialize6961();
paint(0);delay(300);
for(int i=0;i<40;i++){
kletAvt();
paint(0);
}
}
void initialize6961(){
digitalWrite(SSPin,LOW);
digitalWrite(SSPin1,LOW);
digitalWrite(SSPin2,LOW);
SPI.transfer(0b00000011); //command 1
digitalWrite(SSPin,HIGH);
digitalWrite(SSPin1,HIGH);
digitalWrite(SSPin2,HIGH);
digitalWrite(SSPin,LOW);
digitalWrite(SSPin1,LOW);
digitalWrite(SSPin2,LOW);
SPI.transfer(0b01000000); //command 2
digitalWrite(SSPin,HIGH);
digitalWrite(SSPin1,HIGH);
digitalWrite(SSPin2,HIGH);
digitalWrite(SSPin,LOW);
digitalWrite(SSPin1,LOW);
digitalWrite(SSPin2,LOW);
SPI.transfer(0xC0); //command 3
for(int i=0; i<=13; i++){
SPI.transfer(0x00);
}
digitalWrite(SSPin,HIGH);
digitalWrite(SSPin1,HIGH);
digitalWrite(SSPin2,HIGH);
digitalWrite(SSPin,LOW); //command 4
digitalWrite(SSPin1,LOW);
digitalWrite(SSPin2,LOW);
SPI.transfer(vL); //яркость 10001000...10001111
digitalWrite(SSPin,HIGH);
digitalWrite(SSPin1,HIGH);
digitalWrite(SSPin2,HIGH);
}
void clearAll()//выключить все свотодиоды на экране
{
for(int i = 0xc0; i<=0xcd; i++){
digitalWrite(SSPin,LOW);
digitalWrite(SSPin1,LOW);
digitalWrite(SSPin2,LOW);
SPI.transfer(i);
SPI.transfer(0x00);
digitalWrite(SSPin,HIGH);
digitalWrite(SSPin1,HIGH);
digitalWrite(SSPin2,HIGH);
}
}
void clMyArray(int a)//очистка массива или буфера
{
for(int i=0; i<7; i++)
{
for(int j=0; j<29; j++){
if(a==0)
myArray[i][j] = 0;
if(a==1)
myArrayBF[i][j] = 0;
}
}
}
void writeAll()//зажечь все свотодиоды на экране
{
for(int i = 0xc0; i<=0xcd; i++){
digitalWrite(SSPin,LOW);
digitalWrite(SSPin1,LOW);
digitalWrite(SSPin2,LOW);
SPI.transfer(i);
SPI.transfer(0xff);
digitalWrite(SSPin,HIGH);
digitalWrite(SSPin1,HIGH);
digitalWrite(SSPin2,HIGH);
}
}
void paint(byte inv)//рисование из массива на ледматрицу
{
for(int i = 0; i<=6; i++){
r1 = 0;
r2 = 0;
for(int j=10; j>=0; j--){
if(j<=7){
if(myArray[i][j]!=inv)
r1=r1+myArray2[j];
}else{
if(myArray[i][j]!=inv)
r2=r2+myArray2[j];
}
}
digitalWrite(SSPin,LOW);
SPI.transfer(myArray1[i]);
SPI.transfer(r1);
SPI.transfer(r2);
digitalWrite(SSPin,HIGH);
r1 = 0;
r2 = 0;
for(int j=10; j>=0; j--){
if(j<=7){
if(myArray[i][11+j]!=inv)
r1=r1+myArray2[j];
}else{
if(myArray[i][11+j]!=inv)
r2=r2+myArray2[j];
}
}
digitalWrite(SSPin1,LOW);
SPI.transfer(myArray1[i]);
SPI.transfer(r1);
SPI.transfer(r2);
digitalWrite(SSPin1,HIGH);
r1 = 0;
r2 = 0;
for(int j=10; j>=0; j--){
if(j<=7){
if(myArray[i][22+j]!=inv)
r1=r1+myArray2[j];
}else{
if(myArray[i][22+j]!=inv)
r2=r2+myArray2[j];
}
}
digitalWrite(SSPin2,LOW);
SPI.transfer(myArray1[i]);
SPI.transfer(r1);
SPI.transfer(r2);
digitalWrite(SSPin2,HIGH);
}
}
void analogR()//рисование синусоиды, нужно подключить к 1му аналоговому входу линейный выход одного из канала звука
{
val =0;
for(int i=0; i<29; i++){
val = analogRead(0);
if(val!=0 && val<50){
val = (map(val, 0, 50, 0, 2));
}else if(val<481){
val = (map(val, 0, 480, 0, 7));
}else{val=7;}
for(int j=1; j<=val; j++)
myArray[7-j][i] = 1;
}
//paint(inv);
}
void dott_(int ar, int a)//рисование мигающих точек
{
if(millis()-prMillis<500){
if(ar==0){
if(a==0){
arrPrint(ar,8,10);
arrPrint(ar,18,10);
} else if(a == 1){
arrPrint(ar,8,11);
arrPrint(ar,18,11);
}
}else if(ar==1){
if(a==0){
arrPrint(ar,8,10);
arrPrint(ar,18,10);
} else if(a == 1){
arrPrint(ar,8,11);
arrPrint(ar,18,11);
}
}
// prMillis=millis();
}else if(millis()-prMillis<1000){
}else{
prMillis=millis();
}
}
void getTimeDat()//обновление времени и даты в переменных
{
t = rtc.getTime();
valS =t.sec;
valM=t.min;
valH=t.hour;
valD =t.date;
valMon = t.mon;
valY=t.year-2000;
}
void arrPrint(int a, int _j, int vTD)//рисование в массив готовых символов
{
for(int i=0; i<7; i++)
{
for(int j=0; j<3; j++){
if(a==0)
myArray[i][j+_j] = myA0[i][j+3*(vTD)];
if(a==1)
myArrayBF[i][j+_j] = myA0[i][j+3*(vTD)];
}
}
}
void timePr(int a, int vH, int vM, int vS)//рисование в массив времени или даты
{
arrPrint(a,1,vH/10);
arrPrint(a,5,vH%10);
arrPrint(a,11,vM/10);
arrPrint(a,15,vM%10);
arrPrint(a,21,vS/10);
arrPrint(a,25,vS%10);
}
void tehuPr(int a, int vH, int vM)//рисование в массив температуры или влажности
{
if(vH==0){
arrPrint(a,1,13);
arrPrint(a,21,15);
arrPrint(a,25,16);
}else if(vH==1){
arrPrint(a,1,14);
arrPrint(a,21,17);
arrPrint(a,25,18);
myArray[3][24]=1;
}
arrPrint(a,5,12);
arrPrint(a,11,vM/10);
arrPrint(a,15,vM%10);
}
void davlPr(int a, long vP)//рисование в массив давления
{
vP = vP*7.5006/1000;
arrPrint(a,5,int(vP/100));
arrPrint(a,9,int((vP/10)%10));
arrPrint(a,13,int(vP%10));
arrPrint(a,21,20);
arrPrint(a,25,21);
}
int keyBup(int val, int vald)//обработка кнопки + при установки времени
{
if(digitalRead(key_up)==HIGH){
if(millis() - previousMillis > 200)
{
previousMillis = millis();
if(vald<val){
vald++;}else{vald=0;}
}
}
return vald;
}
int keyBdw(int val, int vald)//обработка кнопки - при установки времени
{
if(digitalRead(key_dw)==HIGH){
if(millis() - previousMillis > 200)
{
previousMillis = millis();
if(vald==0){
vald=val;}else{vald--;}
}
}
return vald;
}
int keyBB(int val) //общая обработка кнопок
{
if(millis() - previousMillis > 500)
{
previousMillis = millis();
val++;
val2=0;
}
return val;
}
void readS()//настройка времени и даты
{
if(val0 == 0){
if(digitalRead(bKey1)==HIGH && digitalRead(key_dw)==HIGH){
val0=keyBB(val0);
}
}else{
if(digitalRead(bKey1)==HIGH){
val0=keyBB(val0);
}
}
}
void readSup()//переключение режимов отображения
{
if(digitalRead(key_up)==HIGH && digitalRead(key_dw)==LOW){
val1=keyBB(val1);
}
}
void readL() //изменение яркости
{
if(digitalRead(bKey1)==HIGH){
if(millis() - previousMillis > 200)
{
previousMillis = millis();
if(vL<0x8C){
vL++;
}else{vL=0x89;}
digitalWrite(SSPin,LOW); //command 4
digitalWrite(SSPin1,LOW);
digitalWrite(SSPin2,LOW);
SPI.transfer(vL); //яркость 10001000...10001111
digitalWrite(SSPin,HIGH);
digitalWrite(SSPin1,HIGH);
digitalWrite(SSPin2,HIGH);
}
}
}
void _invers(int b) //инвертирует данные, которые настраиваются в режиме установки времени и даты
{
for(int i=0; i<7; i++)
{
for(int j=0; j<9; j++)
myArray[i][j+b] = !(myArray[i][j+b]);
}
}
void _copyAR(int a) //копия массива в буфер и наоборот
{
for(int i=0; i<7; i++)
{
for(int j=0; j<29; j++){
if(a==0)
myArrayBF[i][j] = myArray[i][j];
if(a==1)
myArray[i][j] = myArrayBF[i][j];
}
}
}
void vizz(int a) //варианты перехода
{
if(a==0){
for(int i=0; i<7; i++){
for(int j=0; j<i;j++){
for(int k=0; k<29; k++)
myArray[j][k] = random(0,2);
paint(inv);
delayMicroseconds(3500);
}
}
for(int i=0; i<7; i++){
for(int j=0; j<(6-i);j++){
_copyAR(1);
for(int k=0; k<29; k++){
myArray[6-j][k] = random(0,2);
}
paint(inv);
delayMicroseconds(3500);
}
}
}else if(a==1){
for(int i=0; i<29; i++){
for(int j=0; j<7; j++){
for(int k=0;k<29;k++){
myArray[j][k] = myArray[j][k+1];
delayMicroseconds(110);
}
}
for(int j =0;j<7;j++){
myArray[j][28] = myArrayBF[j][i];
}
paint(inv);
}
}else if(a==2){
for(int i=0; i<7; i++){
for(int j=0; j<6; j++){
for(int k=0;k<29;k++){
myArray[6-j][k] = myArray[5-j][k];
delayMicroseconds(230);
}
}
for(int j =0;j<29;j++)
myArray[0][j] = myArrayBF[6-i][j];
paint(inv);
}
}
}
int KAI(int i)//вспомогательня функция клеточного автомата
{
if(i<0){
i=6;
}else if(i>6){
i=0;
}
return i;
}
int KAJ(int j)//вспомогательня функция клеточного автомата
{
if(j<0){
j=28;
}else if(j>28){
j=0;
}
return j;
}
void kletAvt()//функция клеточного автомата
{
int _kk=0;
for(int i=0; i<7; i++){
for(int j=0; j<29; j++){
_kk=0;
for(int k=-1; k<2;k++)
_kk += myArray[KAI(i-1)][KAJ(j+k)]+myArray[KAI(i)][KAJ(j+k)]+myArray[KAI(i+1)][KAJ(j+k)];
if(myArray[i][j]==1 && _kk>=3 &&_kk<=4 ){
myArrayBF[i][j]=1;
}else if(myArray[i][j]==1 && _kk<3 && _kk>4){
myArrayBF[i][j]=0;
}else if(myArray[i][j]==0 && _kk==3){
myArrayBF[i][j]=1;
}else{
myArrayBF[i][j]=0;
}
}delay(7);
}
_copyAR(1);
}
void printVR()//переключение режимов отображения
{
switch (val1){
case 0:
if(val2==0){
getTimeDat();
clMyArray(1);
timePr(1,valH,valM,valS);
dott_(1,0);
vizz(0);
val2=1;
}
if(millis()-prMillisTD<100){
getTimeDat();
clMyArray(1);
timePr(1,valH,valM,valS);
dott_(1,0);
vizz(0);
}else if(millis()-prMillisTD<5000){
getTimeDat();
clMyArray(0);
timePr(0,valH,valM,valS);
dott_(0,0);
paint(inv);
}else if(millis()-prMillisTD<5100){
getTimeDat();
clMyArray(1);
timePr(1,valD,valMon,valY);
dott_(1,1);
vizz(0);
}else if(millis()-prMillisTD<8000){
getTimeDat();
clMyArray(0);
timePr(0,valD,valMon,valY);
dott_(0,1);
paint(inv);
}else{
prMillisTD=millis();
}
break;
case 1:
if(val2==0){
getTimeDat();
clMyArray(1);
timePr(1,valD,valMon,valY);
dott_(1,0);
vizz(1);
val2=1;
}
if(millis()-prMillisTD<100){
getTimeDat();
clMyArray(1);
timePr(1,valD,valMon,valY);
dott_(1,1);
vizz(1);
}else if(millis()-prMillisTD<4000){
getTimeDat();
clMyArray(0);
timePr(0,valD,valMon,valY);
dott_(0,1);
paint(inv);
}else if(millis()-prMillisTD<4100){
getTimeDat();
clMyArray(1);
timePr(1,valH,valM,valS);
dott_(1,0);
vizz(1);
}else if(millis()-prMillisTD<10000){
getTimeDat();
clMyArray(0);
timePr(0,valH,valM,valS);
dott_(0,0);
paint(inv);
}else if(millis()-prMillisTD<10100){
DHT11.read(DHT11PIN);
clMyArray(1);
tehuPr(1,0,DHT11.temperature-1);
vizz(2);
}else if(millis()-prMillisTD<12000){
clMyArray(0);
tehuPr(0,0,(int(bmp.readTemperature())));
//dott_(0,1);
paint(inv);
}else if(millis()-prMillisTD<12100){
DHT11.read(DHT11PIN);
clMyArray(1);
tehuPr(1,1,DHT11.humidity);
vizz(2);
}else if(millis()-prMillisTD<14000){
clMyArray(0);
tehuPr(0,1,DHT11.humidity);
//dott_(0,1);
paint(inv);
}else if(millis()-prMillisTD<14100){
clMyArray(1);
davlPr(1,bmp.readPressure());
vizz(2);
}else if(millis()-prMillisTD<16000){
clMyArray(0);
davlPr(0,bmp.readPressure());
paint(inv);
}else{
prMillisTD=millis();
}
break;
case 2:
if(val2==0){
clMyArray(1);
vizz(random(0,3));
val2=1;
}
analogR();
paint(0);
clMyArray(0);
break;
case 3:
if(val2==0){
getTimeDat();
clMyArray(0);
timePr(1,valH,valM,valS);
vizz(0);
val2=1;
}
getTimeDat();
clMyArray(0);
timePr(0,valH,valM,valS);
dott_(0,0);
if(inv==1)
for(int i=0; i<7; i++)
{
for(int j=0; j<29; j++)
myArray[i][j] = !(myArray[i][j]);
}
analogR();
paint(0);
break;
case 4:
kletAvt();
//paint(0);
if(digitalRead(key_dw)==HIGH){
if(millis() - previousMillis > 200)
{
previousMillis = millis();
val2=!val2;
}
}
if(val2==0){
if(millis() - prMillis > 1000){
arrPrint(0,random(0,26),19);
prMillis = millis();
}
}
paint(0);
break;
case 5:
if(digitalRead(key_dw)==HIGH){
if(millis() - previousMillis > 300)
{
previousMillis = millis();
val2=!val2;
}
}
//paint(0);
if(millis()-prMillisTD<1000){
getTimeDat();
clMyArray(0);
timePr(0,valH,valM,valS);
dott_(0,0);
paint(inv);
}else if(millis()-prMillisTD<5000){
kletAvt();
if(val2==0){
if(millis() - prMillis > 1000){
arrPrint(0,random(0,26),19);
prMillis = millis();
}
}
paint(0);
}else{
prMillisTD=millis();
}
break;
case 6:
val1=0;
break;
}
}
void loop() {
readS();
if(digitalRead(key_up)==HIGH && digitalRead(key_dw)==HIGH){
if(millis() - previousMillis > 300)
{
previousMillis = millis();
inv = !inv;}
}
switch (val0){
case 0:
readSup();
readL();
printVR();
break;
case 1:
if(val2==0){
getTimeDat();
val2=1;
}
valS = keyBup(59,valS);
valS = keyBdw(59,valS);
timePr(0,valH,valM,valS);
dott_(0,0);
_invers(20);
paint(0);
clMyArray(0);
break;
case 2:
if(val2==0){
rtc.setTime(valH, valM, valS);
t = rtc.getTime();
valM =t.min;
val2=1;
}
t = rtc.getTime();
valS =t.sec;
valM = keyBup(59,valM);
valM = keyBdw(59,valM);
timePr(0,valH,valM,valS);
dott_(0,0);
_invers(10);
paint(0);
clMyArray(0);
break;
case 3:
if(val2==0){
t = rtc.getTime();
valH =t.hour;
val2=1;
}
t = rtc.getTime();
valS =t.sec;
valH = keyBup(23,valH);
valH = keyBdw(23,valH);
timePr(0,valH,valM,valS);
dott_(0,0);
_invers(0);
paint(0);
clMyArray(0);
break;
case 4:
if(val2==0){
rtc.setTime(valH, valM, valS);
//getTimeDat();
val2=1;
}
valD = keyBup(31,valD);
valD = keyBdw(31,valD);
timePr(0,valD,valMon,valY);
dott_(0,1);
_invers(0);
paint(0);
clMyArray(0);
break;
case 5:
valMon = keyBup(12,valMon);
valMon = keyBdw(12,valMon);
timePr(0,valD,valMon,valY);
dott_(0,1);
_invers(10);
paint(0);
clMyArray(0);
break;
case 6:
valY = keyBup(99,valY);
valY = keyBdw(99,valY);
timePr(0,valD,valMon,valY);
dott_(0,1);
_invers(20);
paint(0);
clMyArray(0);
break;
case 7:
rtc.setDate(valD, valMon, valY+2000);
val0=0;
}
}