Založen: Jul 27, 2004 Příspěvky: 4564 Bydliště: 25km na západ od Prahy
Zaslal: čt duben 27 2023, 12:47 Předmět: IR ovládání místo klávesnice *vyřešeno*
Zahálí mi doma displej IV-18 a chtěl jsem ho využít do hodin co jsou na instructables.com.
S klávesnicí to funguje jak má, po stisku # skočí na zadaní hodnoty a po jejím zadání a potvrzením # skočí na další položku.
Já se po úpravě dostanu po poslání # taky na zadávání položek, ale nedá se nic měnit, protože to pokračuje samo na další položku a tak pořád dokola.
Při úpravě programu jsem nahradil proměnou z klávesnice za proměnou z ovladače.
Chybí mi tam něco nebo je naopak něco navíc?
Založen: Apr 02, 2011 Příspěvky: 18537 Bydliště: Nový Bydžov
Zaslal: čt duben 27 2023, 17:04 Předmět:
Abys nedopadl jako já. Zkoušel jsem HX1838 přijímač s DO, co mi zbylo od STB Philips. Příjem jsem dělal na UNO, jen výpis kódu na Serial monitor. Kódy od stejnejch tlačítek chodily z cca 5 pokusů tak 2 x špatně. A to i na minimální vzdálenost a v úplný tmě.
Zkusil jsem jinej ovladač od Panasonic SVHS, pak ještě od Sharp TV a podobnej problém. Přijímač jsem taky vyměnil a stále stejný. V podstatě nevím, čím to je.
Asi nutnost dobře filtrovat došlý kódy a nesmysly zahazovat. _________________ Jirka
Přečte se z results.value kód klávesy, použije se, ale v tom result.value zůstane a přístě se použije zase, i když už se nic nezmáčkne, jako kdyby se ta klávesa zasekla. Takže by to tam po téhle řádce chtělo ten results.value smazat. Asi tam zapsat třeba tu hodnotu NO_KEY, která se dole testuje.
Takže bych za každý výskyt téhle řádky přidal:
kód:
results.value = NO_KEY;
A pak je tam další problém, že ty kódy kláves jsou 0xFF9867, 0xFFA25D, atd. Původně to asi byly ASCII kódy těch číslic, takže se výrazem (int)key_pressed - 48 získá hodnota té číslice. Jenže to u těchto hausnumer nemůže fungovat. Takže bych tam místo (int)key_pressed - 48 napsal třeba toto:
kód:
hodnota_cislice(key_pressed)
a před tu funkci adjust_field() bych přidal tuhle funkci:
kód:
int hodnota_cislice(int nebo long klavesa) /* okoukat typ te key_pressed */
{
switch ( klavesa )
{
case 0xFF9867: return 0; /* nebo jaka to je klavesa */
case 0xFFA25D: return 1; /* nebo jaka to je klavesa */
......
default: return 0;
}
}
Založen: Jan 01, 2023 Příspěvky: 2057 Bydliště: Česká Lípa
Zaslal: čt duben 27 2023, 19:24 Předmět:
Máte chybně upravenou funkci adjust_field.
Proměnná key_pressed má být typu char (je deklarováno na začátku zdrojáku, který zde celý ani neuvádíte). Proměnná key_pressed je tedy 8-mi bitová se znaménkem a vy do ní podle rozpisu těch hodnot cpete 32-bitové hodnoty z toho IR ovladače tj. první nesmysl.
Další nesmysl je používat ty 32-bitové kódy z IR ovladače jako třeba 0xFF9867 když dále ve funkci adjust_field se evidentně počítá s 8-mi bitovými znaky.
Když se do proměnné key_pressed pokusíte vložit třeba hodnotu 0xFF9867
key_pressed = results.value;
Tak výsledkem bude jen hodnota hexa 0x67 tj. dekadicky 103 tj. znak 'g', a to samozřejmě neodpovídá znaku '0' tj. dekadicky 48 jak by mělo být. Takže je nesprávné předávat hodnoty z IR ovladače dále třeba metodě print objektu lcd.
lcd.print(key_pressed);
Stejně tak vám vycházejí nesmysly třeba při výpočtu nového dne při volání
new_days = (int)key_pressed - 48;
a totéž na dalších místech kde se používá proměnná key_pressed dále ve funkci adjust_field.
Takto to prostě nemůže fungovat.
Je potřeba si udělat funkci pro převod hodnot načtených z IR ovladače na ty klasické hodnoty znaků odpovídající klasické klávesnici tj. '0' až '9' a '#'.
K tomu účelu jsem tam doplnil funkci convert_key. Podle toho rozpisu hodnot jako 0xFF9867 a dalších podobných předpokládám že results.value vrací 32-bitovou hodnotu se znaménkem tj. long. Pokud je to jinak pak je potřeba opravit parametr IR_Key funkce convert_key na správný datový typ.
Upravil jsem funkce adjust_field a check_user_input viz níže.
Jste si skutečně jist těmi hodnotami z IR ovladače jako je třeba 0xFF9867 a další?
Hodnota načtená z ovladače by se měla v tom objektu results, který je předpokládám tím objektem IR ovladače, po zpracováni vynulovat. Na konci konverzní funkce convert_key tedy nuluji hodnotu načteného kódu IR ovladače viz k tomu popis ve zdrojáku na konci funkce convert_key.
Ve funkci adjust_field jsem v té složené podmínce IF nahradil operátor OR za klasický logický operátor ||, který se v jazyce C používá. Ve standardu jazyka C není operátor v podobě slova OR vůbec podporován. I pokud ho Arduino IDE podporuje pravděpodobně pomocí ukryté definice umístěné v některém ze základních hlavičkových souborů, něco jako
#define OR ||
#define or ||
tak je to nestandardní, a proto jsem to raději nahradil tím co se v jazyce C standardně používá.
kód:
// Funkce pro prevod kodu IR_Key na znaky '0' az '9' a '#'
char convert_key (long IR_Key)
{
char Ret = 0;
switch (IR_Key) {
case 0xFF9867:
// predpokladam, ze toto ma byt znak char '0' tj. hodnota dekadicky 48
Ret = 48;
break;
case 0xFFA25D:
// predpokladam, ze toto ma byt znak char '1' tj. hodnota dekadicky 49
Ret = 49;
break;
case 0xFF629D:
// predpokladam, ze toto ma byt znak char '2' tj. hodnota dekadicky 50
Ret = 50;
break;
case 0xFFE21D:
// predpokladam, ze toto ma byt znak char '3' tj. hodnota dekadicky 51
Ret = 51;
break;
case 0xFF22DD:
// predpokladam, ze toto ma byt znak char '4' tj. hodnota dekadicky 52
Ret = 52;
break;
case 0xFF02FD:
// predpokladam, ze toto ma byt znak char '5' tj. hodnota dekadicky 53
Ret = 53;
break;
case 0xFFC23D:
// predpokladam, ze toto ma byt znak char '6' tj. hodnota dekadicky 54
Ret = 54;
break;
case 0xFFE01F:
// predpokladam, ze toto ma byt znak char '7' tj. hodnota dekadicky 55
Ret = 55;
break;
case 0xFFA857:
// predpokladam, ze toto ma byt znak char '8' tj. hodnota dekadicky 56
Ret = 56;
break;
case 0xFF906F:
// predpokladam, ze toto ma byt znak char '9' tj. hodnota dekadicky 57
Ret = 57;
break;
case 0xFFB04F:
// predpokladam, ze toto ma byt znak char '#' tj. hodnota dekadicky 35
Ret = 35;
break;
default:
// nepodporovany znak tj. vrací se hodnota 0
Ret = 0;
break;
}
// Hodnota nactena z ovladace by mela byt v objektu ovladace po zpracovani vynulovana.
// Na konci teto konverzni funkce tedy nuluji hodnotu nacteneho kodu v objektu ovladace results.
// Pokud by nebylo mozne nulovat takto results.value = 0 tak si vyhledejte v objektu
// results prislusnou metodu k nulovani hodnoty, treba neco jako
// results.Clear(); apod.
results.value = 0;
return Ret;
}
void adjust_field(int field)
{
field_value = field;
digits_entered = 13;
// Zmena z
// key_pressed = mykeypad.getKey();
// na
// prevod hodnoty z IR ovladace na hodnotu klavesy
key_pressed = convert_key(results.value);
while (key_pressed != '#')
{
// Zmena z
// key_pressed = mykeypad.getKey();
// na
// prevod hodnoty z IR ovladace na hodnotu klavesy
delay(100);
key_pressed = convert_key(results.value);
delay(100);
// Wait for user to press a key on the keypad
while (key_pressed == 0)
{
// Zmena z
// key_pressed = mykeypad.getKey();
// na
// prevod hodnoty z IR ovladace na hodnotu klavesy
key_pressed = convert_key(results.value);
delay(100);
}
}
}
void adjustValues()
{
now = rtc.now();
// get current time and date, populate adjustment fields.
hourString = now.hour();
minuteString = now.minute();
secondString = now.second();
hour1 = hourString.substring(0,2);
minute1 = minuteString.substring(0,2);
second1 = secondString.substring(0,2);
lcd.clear();
lcd.setCursor(0,0);
lcd.print(" New Values Set");
mp3.volume(chimesVolumn); //Set volume value. From 0 to 30
new_years = 2000 + new_years;
rtc.adjust(DateTime(new_years, new_months, new_days, new_hours, new_minutes, new_seconds));
}
void check_user_input()
{
// Zmena z
// if ((key_pressed = mykeypad.getKey()) != false)
// na
// prevod hodnoty z IR ovladace na hodnotu klavesy
if ((key_pressed = convert_key(results.value)) != 0)
{
if (key_pressed == '#')
{
adjustValues();
}
}
}
Založen: Jul 27, 2004 Příspěvky: 4564 Bydliště: 25km na západ od Prahy
Zaslal: čt duben 27 2023, 20:39 Předmět:
Dík za pomoc, zítra se do toho pustím.
S tím adjust_field. jsem nic nedělal. Vycházel jsem z toho, že s klávesnicí to funguje jak má a že tedy bude stačit upravit čtení kódů ovladače a použít je místo klávesnice.
Ale jak se zdá, není to tak jednoduché jak jsem si myslel. _________________ Kdyby Edison nevynalezl elektřinu, do teď se díváme na televizi při svíčkách.
Založen: Jan 01, 2023 Příspěvky: 2057 Bydliště: Česká Lípa
Zaslal: čt duben 27 2023, 20:51 Předmět:
hafca napsal(a):
Vycházel jsem z toho, že s klávesnicí to funguje jak má a že tedy bude stačit upravit čtení kódů ovladače a použít je místo klávesnice. Ale jak se zdá, není to tak jednoduché jak jsem si myslel.
Takto jednoduše to prostě zaměnit nelze, protože se hodnoty načtených znaků používají pro různé výpočty přičemž se počítá s hodnotami z té původní klávesnice, ale ty hodnoty z ovladače jsou úplně jiné a tudíž pro přímou náhradu nepoužitelné. Takže je potřeba udělat převod hodnot z ovladače na hodnoty odpovídající té původní klávesnici a k tomu jsem do zdrojáku dopsal tu funkci convert_key. Čtení hodnot z klávesnice se používá ve funkci adjust_field na dvou místech, jednou na začátku a podruhé ještě ke konci. Navíc se používá také ještě i ve funkci check_user_input a na všech třech zmíněných místech jsem to upravil tak, že se použije funkce convert_key.
Navíc hodnota načtená z ovladače v tom objektu results by se měla po zpracováni vynulovat, aby tam nezůstávala což by vyvolávalo pořád stejnou událost. Takže jsem na konci konverzní funkce convert_key udělal nulování hodnoty načteného kódu IR ovladače viz k tomu popis ve zdrojáku na konci funkce convert_key.
Otázkou zůstává jestli máte aktualizaci hodnot z ovladače v tom objektu results správně implementovánu, protože ve zdrojáku používáte jen odkaz na už načtenou hodnotu results.value, ale nikde tam nemáte nějaké volání funkce nebo metody aktualizace. Takže buď probíhá aktualizace z ovladače v tom objektu automaticky na pozadí (přes interní přerušení apod.) a nebo vám před každým použitím results.value chybí něco jako results.update() apod. jinak se hodnota nebude z ovladače aktualizovat.
Založen: Jul 27, 2004 Příspěvky: 4564 Bydliště: 25km na západ od Prahy
Zaslal: pá duben 28 2023, 9:38 Předmět:
Zkusil jsem udělat ty navrhované změny v programu, ale žádný úspěch. Kompilace projde, ale to je vše.
Protože se nedá nijak jednoduše sledovat, jestli program nějak reaguje na dálkové ovládání, použil jsem irrecv.blink13(true); na indikaci, jestli signál z ovladače došel kam má.
Zjistil jsem, že ve void check_user_input() se nic neděje. Jedině když posunu adjustValues(); nad poslední závorku, program rovnou skočí bez zásahu ovladače na nastavování hodnot, ale nastavovat se nic nedá.
Jsou moc velké změny a asi dělám něco špatně.
Jen poznámka k převodu čísel z ovladače. Mám malý program a ten ty čísla vypisuje na seriovém monitoru a zároveň dokáže aktivovat nastavený port v závisloti na vyslaném čísle. Proto jsem je používal bez konverze s tím, že když to funguje v malém programu, bude to funkční i tady.
No, budu bádat dál a snad se dopracuji k funkčnímu stavu. _________________ Kdyby Edison nevynalezl elektřinu, do teď se díváme na televizi při svíčkách.
Založen: Jan 01, 2023 Příspěvky: 2057 Bydliště: Česká Lípa
Zaslal: pá duben 28 2023, 13:06 Předmět:
hafca napsal(a):
Zjistil jsem, že ve void check_user_input() se nic neděje. Jedině když posunu adjustValues(); nad poslední závorku, program rovnou skočí bez zásahu ovladače na nastavování hodnot, ale nastavovat se nic nedá.
Jen poznámka k převodu čísel z ovladače. Mám malý program a ten ty čísla vypisuje na seriovém monitoru a zároveň dokáže aktivovat nastavený port v závisloti na vyslaném čísle.
Řekl bych, že vám tam pravděpodobně něco chybí ve smyslu aktualizace hodnot z ovladače jak už jsem zmínil dříve, a proto to ani ve funkci check_user_input() nefunguje tak jak by mělo. Dejte sem celý ten váš upravený zdroják *.ino obsahující i čtení dat z IR ovladače a také zdroják toho programu co čísla vypisuje na seriovém monitoru ať se dá porovnat co vám v tom upraveném zdrojáku případně chybí. Takhle naslepo můžeme jen hádat.
seg. A seg. B seg. C seg. D seg. E seg. F seg. G seg. DP
OUT12 OUT13 OUT14 OUT15 OUT16 OUT17 OUT18 OUT19
PIN 10 9 8 7 6 5 4 3
*/
int rows = 0;
int columns = 0;
int clockPin = 25; // 25,27,29
int loadPin = 27;
int dinPin = 29;
int dataPinRegister[20] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
int offset;
//A F B G E C D,dp
int segmentArray[33][8]={
{ 1,1,1,0,1,1,1,0, }, //0
{ 0,0,1,0,0,1,0,0, }, //1
{ 1,0,1,1,1,0,1,0, }, //2
{ 1,0,1,1,0,1,1,0, }, //3
{ 0,1,1,1,0,1,0,0, }, //4
{ 1,1,0,1,0,1,1,0, }, //5
{ 1,1,0,1,1,1,1,0, }, //6
{ 1,0,1,0,0,1,0,0, }, //7
{ 1,1,1,1,1,1,1,0, }, //8
{ 1,1,1,1,0,1,0,0, }, //9
{ 1,1,1,0,1,1,1,1, }, //0.
{ 0,0,1,0,0,1,0,1, }, //1.
{ 1,0,1,1,1,0,1,1, }, //2.
{ 1,0,1,1,0,1,1,1, }, //3.
{ 0,1,1,1,0,1,0,1, }, //4.
{ 1,1,0,1,0,1,1,1, }, //5.
{ 1,1,0,1,1,1,1,1, }, //6.
{ 1,0,1,0,0,1,0,1, }, //7.
{ 1,1,1,1,1,1,1,1, }, //8.
{ 1,1,1,1,0,1,0,1, }, //9.
{ 0,0,0,1,0,0,0,0, }, //- G segment / W
{ 1,1,0,0,1,0,1,0, }, //C
{ 1,1,0,1,1,0,0,0, }, //F
{ 1,1,1,1,1,0,0,0, }, //P
{ 0,0,0,0,0,0,0,1, }, //.
{ 1,1,1,1,0,0,0,0, }, //Upper o
{ 0,0,1,1,1,0,0,0, }, // Slash
{ 0,0,0,1,1,1,1,0, }, //Lower o
{ 0,0,0,0,0,0,0,0, }, // Blank
{ 0,1,1,1,1,1,0,0, }, // H
{ 0,0,0,0,0,1,0,0, }, //- C segment X
{ 0,0,0,0,0,0,1,0, }, //- D segment Y
{ 0,0,0,0,1,0,0,0, }}; //- E segment Z
#include <Keypad.h>
const byte n_rows= 4; //number of rows on the keypad
const byte n_cols= 4; //number of columns on the keypad
char keymap[n_rows][n_cols]=
{
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
};
//Code that shows the the keypad connections to the arduino terminals
byte colPins[n_rows] = {5, 4, 3, 2};
byte rowPins[n_cols] = {9, 8, 7, 6};
//Specify digital pin on the Arduino that the positive lead of piezo buzzer is attached.
int days = 11;
int months = 3;
int years = 19;
int new_days = 11;
int new_months = 3;
int new_years = 19;
int hours = 16;
int minutes = 11;
int seconds = 20;
int new_hours = 16;
int new_minutes = 11;
int new_seconds = 20;
int found, maxIndex;
int digits_entered = 0;
int j,x,y,k,m,n,i,t,a;
int index1;
int chimesVolumn = 20;
int ldrStatus; // Ambiant light check, less than 600 clock switches off
int ldrLimit = 200;
int sleep_mode = 0;
char testChar,indicator;
void setup()
{
// initialize outputs for MAX6921 chip
pinMode(dinPin, OUTPUT);
pinMode(loadPin, OUTPUT);
pinMode(clockPin, OUTPUT);
digitalWrite(clockPin, LOW);
digitalWrite(loadPin, LOW);
digitalWrite(dinPin, LOW);
irrecv.enableIRIn();
// initialize the lcd
lcd.init();
lcd.backlight();
lcd.clear();
lcd.setCursor(0,0);
lcd.print(" ILC Clock V2.0 ");
rtc.begin(); // Initialize the rtc object
// rtc.adjust(DateTime(2019, 10, 5, 11, 59, 0));
Wire.begin();
bme.setI2CAddress(0x76); //Connect to a second sensor 0x76
if(bme.beginI2C() == false)
{
Serial.println("Sensor B connect failed");
}
indicator = 'W'; // first part of rolling time seperator
sleep_mode = 0;
screenSaveRequired = "Y";
chimesPlayed = "N";
// setup chimes
mySoftwareSerial.begin(9600);
mp3.begin(mySoftwareSerial);
mp3.reset();
mp3.volume(30); //Set volume value. From 0 to 30
}
void loop()
{
light_detection(); // Check that light levels are OK, if dark then switch off Nixie tubes until
// light levels return to full.
if (sleep_mode != 1)
{
DateTime now = rtc.now();
// Display time for 30 seconds
display_time();
lcd_display();
for (t = 1; t <= 400; t++) // equates to a display time of 40 seconds = 4200
{
check_user_input();
display_time(); // Display time on VFD screen
// Check for Chime
if (chimesRequired == "Y" and chimesPlayed == "N")
{
c_check = characterArray[3] + characterArray[4];
if (c_check == "00" or c_check == "15" or c_check == "30" or c_check == "45")
{
play_chimes();
chimesPlayed = "Y";
}
}
}
chimesPlayed = "N";
// Display date
dayString = now.day();
display_date(); // Display date on VFD screen
lcd_display();
for (t = 1; t <= 200; t++) // equates to a display time of 5 seconds = 400
{
check_user_input();
display_date(); // Display date on VFD screen
}
// Display temperature in Celisus
temperatureC = bme.readTempC();
display_temperatureC(); // Display temperatureC on VFD screen
lcd_display();
for (t = 1; t <= 200; t++)
{
check_user_input();
display_temperatureC(); // Display temperatureC on VFD screen
}
// Display temperature in Farenheit
temperatureF = bme.readTempF();
display_temperatureF(); // Display temperatureF on VFD screen
lcd_display();
for (t = 1; t <= 200; t++)
{
check_user_input();
display_temperatureF(); // Display temperatureF on VFD screen
}
// Display pressure in mB
pressure = bme.readFloatPressure()/100.0F;
display_pressure(); // Display pressure on VFD screen
lcd_display();
for (t = 1; t <= 200; t++)
{
check_user_input();
display_pressure(); // Display pressure on VFD screen
}
// Display humidity
humidity = bme.readFloatHumidity();
display_humidity(); // Display humidity on VFD screen
lcd_display();
for (t = 1; t <= 200; t++)
{
check_user_input();
display_humidity(); // Display humidity on VFD screen
}
}
}
void light_detection()
{
ldrStatus = analogRead(A15);
ldrStatus = ldrStatus * 100; // Adjustment for difference between this clock and the original clock
// this will ensure that both clocks switch off approximately at the same time.
sleep_mode = 0;
if (ldrStatus <= ldrLimit and screenSaveRequired == "Y")
{
sleep_mode = 1;
characterArray[0] = " "; // Setup Blank Screen
characterArray[1] = " ";
characterArray[2] = " ";
characterArray[3] = " ";
characterArray[4] = " ";
characterArray[5] = " ";
characterArray[6] = " ";
characterArray[7] = " ";
lcd.setCursor(0,1);
lcd.print(" SLEEP MODE ");
process_display();
}
}
// Funkce pro prevod kodu IR_Key na znaky '0' az '9' a '#'
char convert_key (long IR_Key)
{
char Ret = 0;
switch (IR_Key) {
case 0xFF9867:
// predpokladam, ze toto ma byt znak char '0' tj. hodnota dekadicky 48
Ret = 48;
break;
case 0xFFA25D:
// predpokladam, ze toto ma byt znak char '1' tj. hodnota dekadicky 49
Ret = 49;
break;
case 0xFF629D:
// predpokladam, ze toto ma byt znak char '2' tj. hodnota dekadicky 50
Ret = 50;
break;
case 0xFFE21D:
// predpokladam, ze toto ma byt znak char '3' tj. hodnota dekadicky 51
Ret = 51;
break;
case 0xFF22DD:
// predpokladam, ze toto ma byt znak char '4' tj. hodnota dekadicky 52
Ret = 52;
break;
case 0xFF02FD:
// predpokladam, ze toto ma byt znak char '5' tj. hodnota dekadicky 53
Ret = 53;
break;
case 0xFFC23D:
// predpokladam, ze toto ma byt znak char '6' tj. hodnota dekadicky 54
Ret = 54;
break;
case 0xFFE01F:
// predpokladam, ze toto ma byt znak char '7' tj. hodnota dekadicky 55
Ret = 55;
break;
case 0xFFA857:
// predpokladam, ze toto ma byt znak char '8' tj. hodnota dekadicky 56
Ret = 56;
break;
case 0xFF906F:
// predpokladam, ze toto ma byt znak char '9' tj. hodnota dekadicky 57
Ret = 57;
break;
case 0xFFB04F:
// predpokladam, ze toto ma byt znak char '#' tj. hodnota dekadicky 35
Ret = 35;
break;
default:
// nepodporovany znak tj. vrací se hodnota 0
Ret = 0;
break;
}
// Hodnota nactena z ovladace by mela byt v objektu ovladace po zpracovani vynulovana.
// Na konci teto konverzni funkce tedy nuluji hodnotu nacteneho kodu v objektu ovladace results.
// Pokud by nebylo mozne nulovat takto results.value = 0 tak si vyhledejte v objektu
// results prislusnou metodu k nulovani hodnoty, treba neco jako
// results.Clear(); apod.
results.value = 0;
return Ret;
}
c_check = characterArray[0] + characterArray[1];
process_chime_display();
mp3.play(16);
delay(19000);
if (c_check == "01" or c_check == "13")
{
// Play 1 Hour Chime
mp3.play(1);
delay(3000);
}
if (c_check == "02" or c_check == "14")
{
// Play 2 Hour Chime
mp3.play(2);
delay(5000);
}
if (c_check == "03" or c_check == "15")
{
// Play 3 Hour Chime
mp3.play(3);
delay(7000);
}
if (c_check == "04" or c_check == "16")
{
// Play 4 Hour Chime
mp3.play(4);
delay(9000);
}
if (c_check == "05" or c_check == "17")
{
// Play 5 Hour Chime
mp3.play(5);
delay(11000);
}
if (c_check == "06" or c_check == "18")
{
// Play 6 Hour Chime
mp3.play(6);
delay(13000);
}
if (c_check == "07" or c_check == "19")
{
// Play 7 Hour Chime
mp3.play(7);
delay(15000);
}
if (c_check == "08" or c_check == "20")
{
// Play 8 Hour Chime
mp3.play(8);
delay(17000);
}
if (c_check == "09" or c_check == "21")
{
// Play 9 Hour Chime
mp3.play(9);
delay(19000);
}
if (c_check == "10" or c_check == "22")
{
// Play 10 Hour Chime
mp3.play(10);
delay(21000);
}
if (c_check == "11" or c_check == "23")
{
// Play 11 Hour Chime
mp3.play(11);
delay(23000);
}
if (c_check == "12" or c_check == "00")
{
// Play 12 Hour Chime
mp3.play(12);
delay(25000);
}
}
else {
process_chime_display();
if (c_check == "15") // Sound 15 minute chime
{
// play 15 Minute chime
mp3.play(13);
}
if (c_check == "30") // Sound 30 minute chime
{
// play 30 Minute chime
mp3.play(14);
}
if (c_check == "45") // Sound 45 minute chime
{
// play 45 Minute chime
mp3.play(15);
}
}
}
void check_user_input()
{
// Zmena z
// if ((key_pressed = mykeypad.getKey()) != false)
// na
// prevod hodnoty z IR ovladace na hodnotu klavesy
if ((key_pressed = convert_key(results.value)) != 0)
{
if (key_pressed == '#')
{
adjustValues();
}
}
}
void lcd_display() // Display on the LCD exactly what is stored in the character array.
{
lcd.clear();
lcd.setCursor(0,0);
lcd.print(" ILC Clock V2.0 ");
lcd.setCursor(1,1);
lcd.print(characterArray[0]);
lcd.print(characterArray[1]);
if (characterArray[2] == "W" or characterArray[2] == "X" or characterArray[2] == "Y" or characterArray[2] == "Z")
{
lcd.print(".");
} else
{
lcd.print(characterArray[2]);
}
lcd.print(characterArray[3]);
lcd.print(characterArray[4]);
if (characterArray[2] == "W" or characterArray[2] == "X" or characterArray[2] == "Y" or characterArray[2] == "Z")
{
lcd.print(".");
} else
{
lcd.print(characterArray[5]);
}
lcd.print(characterArray[6]);
lcd.print(characterArray[7]);
}
void display_time()
{
now = rtc.now();
hourString = now.hour();
test = hourString.length();
if (test == 1)
{
hour1 = " ";
hour2 = hourString.substring(0,1);
}
else {
hour1 = hourString.substring(0,1);
hour2 = hourString.substring(1,2);
}
minuteString = now.minute();
test = minuteString.length();
if (test == 1)
{
minute1 = "0";
minute2 = minuteString.substring(0,1);
}
else {
minute1 = minuteString.substring(0,1);
minute2 = minuteString.substring(1,2);
}
secondString = now.second();
test = secondString.length();
if (test == 1)
{
second1 = "0";
second2 = secondString.substring(0,1);
}
else {
second1 = secondString.substring(0,1);
second2 = secondString.substring(1,2);
}
characterArray[0] = hour1;
characterArray[1] = hour2;
characterArray[2] = indicator;
characterArray[3] = minute1;
characterArray[4] = minute2;
characterArray[5] = indicator;
characterArray[6] = second1;
characterArray[7] = second2;
if(second2 != save_second2) // Move the indicator one position at the change of each second
{
if (indicator == 'W')
{
indicator = 'X';
} else if (indicator == 'X')
{
indicator = 'Y';
} else if (indicator == 'Y')
{
indicator = 'Z';
} else {
indicator = 'W';
}
save_second2 = second2;
}
if (key_pressed == 0xFF9867 or key_pressed == 0xFFA25D or key_pressed == 0xFF629D or
key_pressed == 0xFFE21D or key_pressed == 0xFF22DD or key_pressed == 0xFF02FD or
key_pressed == 0xFFC23D or key_pressed == 0xFFE01F or key_pressed == 0xFFA857 or
key_pressed == 0xFF906F)
{
long cti_klavesu()
{
long klavesa;
if (irrecv.decode(&results))
{
klavesa = results.value;
irrecv.resume();
}
else
{
klavesa = 0;
}
return klavesa;
}
int cti_znak()
{
switch ( cti_klavesu() )
{
case 0: return 0;
case 0xFF9867: return '0';
case 0xFFA25D: return '1';
a tak dale
case 0xFFB04F: return '#';
default: 0;
}
}
No a tu funkci cti_znak() bych volal pro čtení znaku.
Založen: Jan 01, 2023 Příspěvky: 2057 Bydliště: Česká Lípa
Zaslal: pá duben 28 2023, 20:18 Předmět:
hafca napsal(a):
Tohle je komplet s úpravami co tady byly navržené.
To tedy nebylo.
Proměnnou key_pressed jste měl deklarovanou jako datový typ long i když má být char.
Zapoměl jste doplnit volání funkce convert_key na dvou místech ve funkci adjust_field.
Nikde v programu jste nenačítal hodnotu z ovladače do results tj. nikde jste nevolal irrecv.decode(&results) ani irrecv.resume().
Funkci convert_key jsem ještě upravil tak, že nyní volá irrecv.decode(&results) ani irrecv.resume() a nepotřebuje žádný parametr.
Ve funkci adjust_field jsme nechal ty předchozí nesmysly
kód:
while (key_pressed != 0xFFB04F)
{
if (key_pressed == 0xFF9867 or key_pressed == 0xFFA25D or key_pressed == 0xFF629D or
key_pressed == 0xFFE21D or key_pressed == 0xFF22DD or key_pressed == 0xFF02FD or
key_pressed == 0xFFC23D or key_pressed == 0xFFE01F or key_pressed == 0xFFA857 or
key_pressed == 0xFF906F) {
seg. A seg. B seg. C seg. D seg. E seg. F seg. G seg. DP
OUT12 OUT13 OUT14 OUT15 OUT16 OUT17 OUT18 OUT19
PIN 10 9 8 7 6 5 4 3
*/
int rows = 0;
int columns = 0;
int clockPin = 25; // 25,27,29
int loadPin = 27;
int dinPin = 29;
int dataPinRegister[20] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
int offset;
//A F B G E C D,dp
int segmentArray[33][8]={
{ 1,1,1,0,1,1,1,0, }, //0
{ 0,0,1,0,0,1,0,0, }, //1
{ 1,0,1,1,1,0,1,0, }, //2
{ 1,0,1,1,0,1,1,0, }, //3
{ 0,1,1,1,0,1,0,0, }, //4
{ 1,1,0,1,0,1,1,0, }, //5
{ 1,1,0,1,1,1,1,0, }, //6
{ 1,0,1,0,0,1,0,0, }, //7
{ 1,1,1,1,1,1,1,0, }, //8
{ 1,1,1,1,0,1,0,0, }, //9
{ 1,1,1,0,1,1,1,1, }, //0.
{ 0,0,1,0,0,1,0,1, }, //1.
{ 1,0,1,1,1,0,1,1, }, //2.
{ 1,0,1,1,0,1,1,1, }, //3.
{ 0,1,1,1,0,1,0,1, }, //4.
{ 1,1,0,1,0,1,1,1, }, //5.
{ 1,1,0,1,1,1,1,1, }, //6.
{ 1,0,1,0,0,1,0,1, }, //7.
{ 1,1,1,1,1,1,1,1, }, //8.
{ 1,1,1,1,0,1,0,1, }, //9.
{ 0,0,0,1,0,0,0,0, }, //- G segment / W
{ 1,1,0,0,1,0,1,0, }, //C
{ 1,1,0,1,1,0,0,0, }, //F
{ 1,1,1,1,1,0,0,0, }, //P
{ 0,0,0,0,0,0,0,1, }, //.
{ 1,1,1,1,0,0,0,0, }, //Upper o
{ 0,0,1,1,1,0,0,0, }, // Slash
{ 0,0,0,1,1,1,1,0, }, //Lower o
{ 0,0,0,0,0,0,0,0, }, // Blank
{ 0,1,1,1,1,1,0,0, }, // H
{ 0,0,0,0,0,1,0,0, }, //- C segment X
{ 0,0,0,0,0,0,1,0, }, //- D segment Y
{ 0,0,0,0,1,0,0,0, }}; //- E segment Z
#include <Keypad.h>
const byte n_rows= 4; //number of rows on the keypad
const byte n_cols= 4; //number of columns on the keypad
char keymap[n_rows][n_cols]=
{
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
};
//Code that shows the the keypad connections to the arduino terminals
byte colPins[n_rows] = {5, 4, 3, 2};
byte rowPins[n_cols] = {9, 8, 7, 6};
//Specify digital pin on the Arduino that the positive lead of piezo buzzer is attached.
int days = 11;
int months = 3;
int years = 19;
int new_days = 11;
int new_months = 3;
int new_years = 19;
int hours = 16;
int minutes = 11;
int seconds = 20;
int new_hours = 16;
int new_minutes = 11;
int new_seconds = 20;
int found, maxIndex;
int digits_entered = 0;
int j,x,y,k,m,n,i,t,a;
int index1;
int chimesVolumn = 20;
int ldrStatus; // Ambiant light check, less than 600 clock switches off
int ldrLimit = 200;
int sleep_mode = 0;
char testChar,indicator;
void setup()
{
// initialize outputs for MAX6921 chip
pinMode(dinPin, OUTPUT);
pinMode(loadPin, OUTPUT);
pinMode(clockPin, OUTPUT);
digitalWrite(clockPin, LOW);
digitalWrite(loadPin, LOW);
digitalWrite(dinPin, LOW);
irrecv.enableIRIn();
// initialize the lcd
lcd.init();
lcd.backlight();
lcd.clear();
lcd.setCursor(0,0);
lcd.print(" ILC Clock V2.0 ");
rtc.begin(); // Initialize the rtc object
// rtc.adjust(DateTime(2019, 10, 5, 11, 59, 0));
Wire.begin();
bme.setI2CAddress(0x76); //Connect to a second sensor 0x76
if(bme.beginI2C() == false)
{
Serial.println("Sensor B connect failed");
}
indicator = 'W'; // first part of rolling time seperator
sleep_mode = 0;
screenSaveRequired = "Y";
chimesPlayed = "N";
// setup chimes
mySoftwareSerial.begin(9600);
mp3.begin(mySoftwareSerial);
mp3.reset();
mp3.volume(30); //Set volume value. From 0 to 30
}
void loop()
{
// Check that light levels are OK, if dark then switch off Nixie tubes until
// light levels return to full.
light_detection();
if (sleep_mode != 1) {
DateTime now = rtc.now();
// Display time for 30 seconds
display_time();
lcd_display();
// equates to a display time of 40 seconds = 4200
for (t = 1; t <= 400; t++)
{
check_user_input();
// Display time on VFD screen
display_time();
// Check for Chime
if (chimesRequired == "Y" && chimesPlayed == "N") {
c_check = characterArray[3] + characterArray[4];
if (c_check == "00" || c_check == "15" || c_check == "30" || c_check == "45") {
play_chimes();
chimesPlayed = "Y";
}
}
}
chimesPlayed = "N";
// Display date
dayString = now.day();
// Display date on VFD screen
display_date();
lcd_display();
// equates to a display time of 5 seconds = 400
for (t = 1; t <= 200; t++)
{
check_user_input();
// Display date on VFD screen
display_date();
}
// Display temperature in Celisus
temperatureC = bme.readTempC();
// Display temperatureC on VFD screen
display_temperatureC();
lcd_display();
for (t = 1; t <= 200; t++)
{
check_user_input();
// Display temperatureC on VFD screen
display_temperatureC();
}
// Display temperature in Farenheit
temperatureF = bme.readTempF();
// Display temperatureF on VFD screen
display_temperatureF();
lcd_display();
for (t = 1; t <= 200; t++)
{
check_user_input();
// Display temperatureF on VFD screen
display_temperatureF();
}
// Display pressure in mB
pressure = bme.readFloatPressure()/100.0F;
// Display pressure on VFD screen
display_pressure();
lcd_display();
for (t = 1; t <= 200; t++)
{
check_user_input();
// Display pressure on VFD screen
display_pressure();
}
// Display humidity
humidity = bme.readFloatHumidity();
// Display humidity on VFD screen
display_humidity();
lcd_display();
for (t = 1; t <= 200; t++)
{
check_user_input();
// Display humidity on VFD screen
display_humidity();
}
}
}
void light_detection()
{
ldrStatus = analogRead(A15);
// Adjustment for difference between this clock and the original clock
// this will ensure that both clocks switch off approximately at the same time.
ldrStatus = ldrStatus * 100;
sleep_mode = 0;
if (ldrStatus <= ldrLimit && screenSaveRequired == "Y") {
sleep_mode = 1;
// Setup Blank Screen
characterArray[0] = " ";
characterArray[1] = " ";
characterArray[2] = " ";
characterArray[3] = " ";
characterArray[4] = " ";
characterArray[5] = " ";
characterArray[6] = " ";
characterArray[7] = " ";
lcd.setCursor(0,1);
lcd.print(" SLEEP MODE ");
process_display();
}
}
// Funkce pro nacteni a prevod kodu z IR ovladace na znaky '0' az '9' a '#'
char convert_key ()
{
char Ret = 0;
results.value = 0;
// nacteni kodu z IR ovladace
if (irrecv.decode(&results)) {
// uspesne nacteno, prikazem resume povolime dalsi cteni do budocuna
irrecv.resume();
} else {
// nenacteno
results.value = 0;
}
delay(100);
switch (results.value) {
case 0xFF9867:
// predpokladam, ze toto ma byt znak char '0' tj. hodnota dekadicky 48
Ret = 48;
break;
case 0xFFA25D:
// predpokladam, ze toto ma byt znak char '1' tj. hodnota dekadicky 49
Ret = 49;
break;
case 0xFF629D:
// predpokladam, ze toto ma byt znak char '2' tj. hodnota dekadicky 50
Ret = 50;
break;
case 0xFFE21D:
// predpokladam, ze toto ma byt znak char '3' tj. hodnota dekadicky 51
Ret = 51;
break;
case 0xFF22DD:
// predpokladam, ze toto ma byt znak char '4' tj. hodnota dekadicky 52
Ret = 52;
break;
case 0xFF02FD:
// predpokladam, ze toto ma byt znak char '5' tj. hodnota dekadicky 53
Ret = 53;
break;
case 0xFFC23D:
// predpokladam, ze toto ma byt znak char '6' tj. hodnota dekadicky 54
Ret = 54;
break;
case 0xFFE01F:
// predpokladam, ze toto ma byt znak char '7' tj. hodnota dekadicky 55
Ret = 55;
break;
case 0xFFA857:
// predpokladam, ze toto ma byt znak char '8' tj. hodnota dekadicky 56
Ret = 56;
break;
case 0xFF906F:
// predpokladam, ze toto ma byt znak char '9' tj. hodnota dekadicky 57
Ret = 57;
break;
case 0xFFB04F:
// predpokladam, ze toto ma byt znak char '#' tj. hodnota dekadicky 35
Ret = 35;
break;
default:
// nepodporovany znak tj. vrací se hodnota 0
Ret = 0;
break;
}
return Ret;
}
Založen: Jul 27, 2004 Příspěvky: 4564 Bydliště: 25km na západ od Prahy
Zaslal: so duben 29 2023, 7:59 Předmět:
FUNGUJE TO! Velký dík za věnovaný čas.
Já se v těch úpravách ztratil a na něco i zapoměl. Bylo to na moje zkušenosti moc velké sousto. _________________ Kdyby Edison nevynalezl elektřinu, do teď se díváme na televizi při svíčkách.
Nemůžete odesílat nové téma do tohoto fóra. Nemůžete odpovídat na témata v tomto fóru. Nemůžete upravovat své příspěvky v tomto fóru. Nemůžete mazat své příspěvky v tomto fóru. Nemůžete hlasovat v tomto fóru. Nemůžete připojovat soubory k příspěvkům Můžete stahovat a prohlížet přiložené soubory
Informace na portálu Elektro bastlírny jsou prezentovány za účelem vzdělání čtenářů a rozšíření zájmu o elektroniku. Autoři článků na serveru neberou žádnou zodpovědnost za škody vzniklé těmito zapojeními. Rovněž neberou žádnou odpovědnost za případnou újmu na zdraví vzniklou úrazem elektrickým proudem. Autoři a správci těchto stránek nepřejímají záruku za správnost zveřejněných materiálů. Předkládané informace a zapojení jsou zveřejněny bez ohledu na případné patenty třetích osob. Nároky na odškodnění na základě změn, chyb nebo vynechání jsou zásadně vyloučeny. Všechny registrované nebo jiné obchodní známky zde použité jsou majetkem jejich vlastníků. Uvedením nejsou zpochybněna z toho vyplývající vlastnická práva. Použití konstrukcí v rozporu se zákonem je přísně zakázáno. Vzhledem k tomu, že původ předkládaných materiálů nelze žádným způsobem dohledat, nelze je použít pro komerční účely! Tento nekomerční server nemá z uvedených zapojení či konstrukcí žádný zisk. Nezodpovídáme za pravost předkládaných materiálů třetími osobami a jejich původ. V případě, že zjistíte porušení autorského práva či jiné nesrovnalosti, kontaktujte administrátory na diskuzním fóru EB.