|
Виж темите без отговор | Виж активните теми
Дата и час: Вто Юли 28, 2026 1:18 am
Сверяване чрез матрична клавиатура
| Автор |
Съобщение |
|
morpheous87
Ранг: Ориентиран
Регистриран на: Съб Авг 07, 2010 8:47 pm Мнения: 239 Местоположение: София
|
 Сверяване чрез матрична клавиатура
Здравейте, направил съм програмка за Ардуино ( по-точно съм събрал на едно няколко по-малки програмки). Програмата се състои в изобразване на часовник, дата, ден и температура. Сензора е ТМР36, а RTC - DS1307. Всичко върви добре, но искам да мога да сверявам нещата след като пусна програмата посредством матрична 3х4 клавиатура. Срещам сериозни проблеми с написването на кода за сверяването обаче... Идеята ми е когато се натисне # на клавиатурата да се влезе в режим за сверяване, да се изредят една по една всички променливи и да заработи после програмата в нормалният й режим. За целта съм направил две функции - waitForKey() (която чака да се натисне бутон в рамките на 10сек. , ), и setClock() (която трябва да облужва натиснатите бутони, да разбира, кой бутон за кое се отнася и т.н)
 |  |  |  | Код: #include "Wire.h" #include <Keypad.h> #define DS1307_I2C_ADDRESS 0x68 #include <LiquidCrystal.h> // we need this library for the LCD commands LiquidCrystal lcd(12, 11, 10, 5, 4, 3, 2); int countPressed; /* Ot tuk e za keypad*/ const byte ROWS = 4; //four rows const byte COLS = 3; //three columns char keys[ROWS][COLS] = { {'1','2','3'}, {'4','5','6'}, {'7','8','9'}, {'#','0','#'} }; byte rowPins[ROWS] = { 9, 8, 7, 6}; //connect to the row pinouts of the keypad byte colPins[COLS] = { 13, 1, 0}; //connect to the column pinouts of the keypad
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS ); /* do tuk e za keypad*/ // Convert normal decimal numbers to binary coded decimal byte decToBcd(byte val) { return ( (val/10*16) + (val%10) ); } // Convert binary coded decimal to normal decimal numbers byte bcdToDec(byte val) { return ( (val/16*10) + (val%16) ); } // 1) Sets the date and time on the ds1307 // 2) Starts the clock // 3) Sets hour mode to 24 hour clock // Assumes you're passing in valid numbers void setDateDs1307(byte second, // 0-59 byte minute, // 0-59 byte hour, // 1-23 byte dayOfWeek, // 1-7 byte dayOfMonth, // 1-28/29/30/31 byte month, // 1-12 byte year) // 0-99 { Wire.beginTransmission(DS1307_I2C_ADDRESS); Wire.send(0); Wire.send(decToBcd(second)); // 0 to bit 7 starts the clock Wire.send(decToBcd(minute)); Wire.send(decToBcd(hour)); Wire.send(decToBcd(dayOfWeek)); Wire.send(decToBcd(dayOfMonth)); Wire.send(decToBcd(month)); Wire.send(decToBcd(year)); Wire.send(0x10); // sends 0x10 (hex) 00010000 (binary) to control register - turns on square wave Wire.endTransmission(); } // Gets the date and time from the ds1307 void getDateDs1307(byte *second, byte *minute, byte *hour, byte *dayOfWeek, byte *dayOfMonth, byte *month, byte *year) { // Reset the register pointer Wire.beginTransmission(DS1307_I2C_ADDRESS); Wire.send(0); Wire.endTransmission(); Wire.requestFrom(DS1307_I2C_ADDRESS, 7); // A few of these need masks because certain bits are control bits *second = bcdToDec(Wire.receive() & 0x7f); *minute = bcdToDec(Wire.receive()); *hour = bcdToDec(Wire.receive() & 0x3f); // Need to change this if 12 hour am/pm *dayOfWeek = bcdToDec(Wire.receive()); *dayOfMonth = bcdToDec(Wire.receive()); *month = bcdToDec(Wire.receive()); *year = bcdToDec(Wire.receive()); } void setup() { byte second, minute, hour, dayOfWeek, dayOfMonth, month, year; Wire.begin(); // Change these values to what you want to set your clock to. // You probably only want to set your clock once and then remove // the setDateDs1307 call. second = 0; minute = 23; hour = 23; dayOfWeek = 4; dayOfMonth = 19; month = 5; year = 10; // setDateDs1307(second, minute, hour, dayOfWeek, dayOfMonth, month, year); lcd.begin(16, 2); // tells Arduino the LCD dimensions lcd.setCursor(0,0); lcd.print(" Miroslav's "); // print text and move cursor to start of next line lcd.setCursor(0,1); lcd.print("Diplomna Rabota "); delay(5000); lcd.clear(); // clear LCD screen } int waitForKey() { char key = keypad.getKey(); if (key != NO_KEY){ if (key == '#') { int key = NO_KEY; unsigned long _start_time = millis(); int countPressed = 0; while(((key = keypad.getKey()) == NO_KEY) && ((millis()-_start_time) < 10000)) { // Do nothing if(key==PRESSED) { countPressed++; setClock(); return key; } } return key; } } return countPressed; } int setClock() { char key = keypad.getKey(); switch(countPressed) { int first_hour; int first_minute; int second_hour; int second_minute; case 1: lcd.print ("Hours:"); first_hour = key; return first_hour; case 2: lcd.print ("Hours:"); lcd.print (first_hour); second_hour = key; return second_hour; case 3: lcd.print ("Minutes:"); first_minute = key; return first_minute; case 4: lcd.print ("Minutes"); lcd.print (first_minute) ; second_minute = key; return second_minute; } } void loop() { char key = keypad.getKey(); if (key != NO_KEY) { waitForKey(); } int sensorPin = 0; int reading = analogRead(sensorPin);
// converting that reading to voltage, for 3.3v arduino use 3.3 float voltage = reading * 5.0 / 1024; // print out the voltage // now print out the temperature float temperatureC = (voltage - 0.5) * 100 ; byte second, minute, hour, dayOfWeek, dayOfMonth, month, year; getDateDs1307(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year); lcd.clear(); // clear LCD screen lcd.setCursor(0,0); lcd.print(hour, DEC); lcd.print(":"); if (minute<10) { lcd.print("0"); } lcd.print(minute, DEC); lcd.print(":"); if (second<10) { lcd.print("0"); } lcd.print(second, DEC); lcd.print(" "); lcd.print(temperatureC); lcd.print("C"); lcd.setCursor(0,1); lcd.print(" "); switch(dayOfWeek){ case 1: lcd.print("Sun"); break; case 2: lcd.print("Mon"); break; case 3: lcd.print("Tue"); break; case 4: lcd.print("Wed"); break;
case 5: lcd.print("Thu"); break; case 6: lcd.print("Fri"); break; case 7: lcd.print("Sat"); break; } lcd.print(" "); lcd.print(dayOfMonth, DEC); lcd.print("/"); lcd.print(month, DEC); lcd.print("/20"); lcd.print(year, DEC); delay(1000); }
|  |  |  |  |
Последна промяна morpheous87 на Вто Авг 24, 2010 10:39 pm, променена общо 1 път
|
| Вто Авг 24, 2010 9:44 pm |
|
 |
|
michev
Ранг: Форумен бог
Регистриран на: Сря Юли 11, 2007 10:16 am Мнения: 1730
|
Не знам точно на Ц ли се пише за ардуино, съответно не му знам и библиотеките му, но определенот ей тоя пасаж е лишен от всякаква логика
ИФ-а никога няма да е true...
Може би си изпуснал преди ИФ-а да сложиш key= keypad.getKey(); ??
Има и друго - ако случайно клавиша е натиснат непосредствено след ИФ-а, то условието на уайла ще пропадне.
|
| Вто Авг 24, 2010 10:26 pm |
|
 |
|
morpheous87
Ранг: Ориентиран
Регистриран на: Съб Авг 07, 2010 8:47 pm Мнения: 239 Местоположение: София
|
Дали може да се направи без функции, а с някаква поредица от if, switch и while?
|
| Сря Авг 25, 2010 8:33 am |
|
 |
|
michev
Ранг: Форумен бог
Регистриран на: Сря Юли 11, 2007 10:16 am Мнения: 1730
|
.... може, що да не може
|
| Сря Авг 25, 2010 10:24 am |
|
 |
|
morpheous87
Ранг: Ориентиран
Регистриран на: Съб Авг 07, 2010 8:47 pm Мнения: 239 Местоположение: София
|
Промених малко насоката за опита с матричната клавиатура. Мисля, че сегашният вариант е по-лесен за мен. Но имам проблем с един switch(). Първият switch() с case '#' работи добре, но вторият не. С него целта ми е да сортирам кой бутон е натиснат и да го съхраня под int-форма за да мога след това да образувам новите стойности. Не дава грешки, но на дисплея не изобразява нищо...
P.S. С този кратък код изобразява на дисплея но вместо да изобрази каквото трябва изобразява две успоредни линии - || . Защо така?
|
| Сря Авг 25, 2010 5:13 pm |
|
 |
|
morpheous87
Ранг: Ориентиран
Регистриран на: Съб Авг 07, 2010 8:47 pm Мнения: 239 Местоположение: София
|
Има ли възможност и ако да, как да се върна назад в програмата ако долният if() ( if(new_minute>=60)), е вярно условието му?
|
| Чет Авг 26, 2010 8:51 am |
|
 |
|
michev
Ранг: Форумен бог
Регистриран на: Сря Юли 11, 2007 10:16 am Мнения: 1730
|
Можеш с goto, но определено това е най - неправилния начин.
Помисли малко, как да си измениш кода, та да позлваш while, break, continue вместо goto или пък го разбий на функции.
|
| Чет Авг 26, 2010 10:48 am |
|
 |
|
Predator_MF
Ранг: Форумен бог
Регистриран на: Чет Окт 07, 2004 1:22 pm Мнения: 1949 Местоположение: София
|
Затваряш целия код в
Кода е и безмислено обемен, всички case ти правят едно и също нещо, можеш доста да го опростиш, вместо всички тия case '0', case '1', нужно е само
Можеш още доста да опростиш нещата, като направиш second_minute просто pointer към това, което ще се наглася (горна минута, долна минута, секунда и пр) и като превключваш различните режими казваш на pointer да сочи към съответните променливи
|
| Чет Авг 26, 2010 11:22 am |
|
 |
|
morpheous87
Ранг: Ориентиран
Регистриран на: Съб Авг 07, 2010 8:47 pm Мнения: 239 Местоположение: София
|
Адски МНОГО БЛАГОДАРЯ!!! Много ми помогна, тъкмо бях в безизходица защото 168цата се напълни и не оставаше място. 
|
| Чет Авг 26, 2010 1:04 pm |
|
 |
|
morpheous87
Ранг: Ориентиран
Регистриран на: Съб Авг 07, 2010 8:47 pm Мнения: 239 Местоположение: София
|
Как мога да огранича да ми изписва до 1 знак след десетичната запетая следният израз: Това не успях много да го схвана... -
|
| Чет Авг 26, 2010 7:32 pm |
|
 |
|
Predator_MF
Ранг: Форумен бог
Регистриран на: Чет Окт 07, 2004 1:22 pm Мнения: 1949 Местоположение: София
|
Там където принтваш temperatureC, вероятно ползваш sprintf, ползвай sprintf(str, "%.01f", temperatureC). Ако не се лъжа работи и в CCS с тоя формат, върти ми се нещо от сорта на 2.1w в главата ама даже не съм инсталирал CCS, че да го ровя в документацията.
|
| Пет Авг 27, 2010 11:18 am |
|
 |
|
michev
Ранг: Форумен бог
Регистриран на: Сря Юли 11, 2007 10:16 am Мнения: 1730
|
Ей тук има пример за форматирано изписване на числа в/у лцд.
За твоето конкретно изискване го направи на
|
| Пет Авг 27, 2010 11:51 am |
|
 |
|
morpheous87
Ранг: Ориентиран
Регистриран на: Съб Авг 07, 2010 8:47 pm Мнения: 239 Местоположение: София
|
Aз изобразявам на дисплея по следният начин -
|
| Пет Авг 27, 2010 5:07 pm |
|
 |
|
michev
Ранг: Форумен бог
Регистриран на: Сря Юли 11, 2007 10:16 am Мнения: 1730
|
Щом си държиш на твойто си - използвай функцията, която Predator_MF ти е дал.
Нещо от тоя сорт трябва да ти е кода
|
| Пет Авг 27, 2010 5:38 pm |
|
 |
|
morpheous87
Ранг: Ориентиран
Регистриран на: Съб Авг 07, 2010 8:47 pm Мнения: 239 Местоположение: София
|
Пробвах , не иска по този начин...
|
| Пет Авг 27, 2010 7:53 pm |
|
|
Кой е на линия |
Потребители разглеждащи този форум: 0 регистрирани и 4 госта |
|
Вие не можете да пускате нови теми Вие не можете да отговаряте на теми Вие не можете да променяте собственото си мнение Вие не можете да изтривате собствените си мнения Вие не можете да прикачвате файл
|
|