Kde mám chybu - switch

Wiring, C++, C, Java, ...
Pravidla fóra
Toto subfórum slouží k řešení obecných otázek kolem programování (konstrukce, knihovny, alokace paměti, ...)
gilhad
Příspěvky: 508
Registrován: 07 bře 2018, 11:22
Reputation: 5

Re: Kde mám chybu - switch

Příspěvek od gilhad » 12 led 2020, 10:07

No nevim, ja bych na to sel tak, ze pokud nacitam cisla od 0 do 99, tak bych nacetl maximalne dva znaky v rozsahu 0-9 a jeden navic. Pokud by ten navic nebyl konec radku, nebo by prvni nebyl cislice, tak uzivateli vynadam, doctu a zahodim zbytek radku a zkusim to znova. Takze mam dve cislice, ty snadno prevedu na cislo v rozsahu byte a overim, zda mi dava smysl - kdyz se nevejde do zadanych mezi, uzivateli vynadam a ctu znova.

Pokud by byl rozsah vetsi, tak pouziju unsigned int a ctu az 4 cifry, pokud by byl jeste vetsi, pouziju unsigned long a ctu tech cifer vic.

(Vynadam uzivateli = zobrazim napovedu typu "Zadejte cislo od 1 do 20 a stisknete Enter - vas vstup selhal, protoze znak "," na pozici 3 nelze pouzit" nebo tak neco)

AstroMiK
Příspěvky: 299
Registrován: 08 pro 2017, 19:05
Reputation: 1

Re: Kde mám chybu - switch

Příspěvek od AstroMiK » 12 led 2020, 10:29

gilhad píše:
12 led 2020, 10:07
V podstatě to tak mám v tom předchozím příkladu. Akorát mám připravený prostor na 9 zadaných znaků.
Navíc tam ještě testuji znak '+' na první pozici a případ, kdy není zadaný žádný znak.

Taky je třeba pamatovat na to, že zadaný řetězec nemusí končit Enterem. Záleží na nastavení sériového terminálu.

Ale jinak to asi řešíme stejně:

1) Načíst znaky ze sériové linky do pole znaků.
2) Když je v sériové lince ještě něco navíc, tak to smazat (vyprázdnit buffer)
3) Brát z pole znak po znaku a když nevyhovuje podmínce (znak >= '0' and znak <= '9') zapamatovat si, že mám vynadat uživateli
(s jedinou výjimkou, kdy je na začátku znak '+' to může být v pořádku).

4) Když projdu celé pole, kouknu, jestli mám zapamatováno, že mám vynadat uživateli a když ne, převedu pole znaků do unsigned long - funkce atoi().

kiRRow
Příspěvky: 485
Registrován: 07 kvě 2019, 07:03
Reputation: 2
Bydliště: Opava

Re: Kde mám chybu - switch

Příspěvek od kiRRow » 12 led 2020, 10:34

Už při načítání jednotlivých znaků bych kontroloval co z toho leze ... pokud je to v rozsahu ASCII "48" až "57" ... jedná se o číslo. Jinak nadávám. Popř toleruji, nebo přímo vyžaduji a kontroluji znaky "10" a "13"

gilhad
Příspěvky: 508
Registrován: 07 bře 2018, 11:22
Reputation: 5

Re: Kde mám chybu - switch

Příspěvek od gilhad » 12 led 2020, 10:42

kiRRow píše:
12 led 2020, 10:34
Už při načítání jednotlivých znaků bych kontroloval co z toho leze ... pokud je to v rozsahu ASCII "48" až "57" ... jedná se o číslo. Jinak nadávám. Popř toleruji, nebo přímo vyžaduji a kontroluji znaky "10" a "13"
Taky to tak beru - vynadat uzivateli co nejdriv :) (+ na zacatku je zbytecne, ale slo by to overit, +uvnitr je chyba).

Navic s timto pristupem muzu testovat i na jine terminatory, pokud za tim ma neco nasledovat, tak to zbytecne nesezeru (napriklad zadani souradnic 10,12 nebo vzorce 1+2-3*4 - porad se zastavim na konci prvniho cisla a nesezeru zbytek retezce, ktery bych pracne lovil)

kiRRow
Příspěvky: 485
Registrován: 07 kvě 2019, 07:03
Reputation: 2
Bydliště: Opava

Re: Kde mám chybu - switch

Příspěvek od kiRRow » 12 led 2020, 10:52

No jako v praxi, pokud se něco ovládá po seriové lince, tak jsem ještě nikdy neviděl, že by uživatel přímo měl terminál a bylo mu dovoleno solit do toho cokoliv co ho napadne. Uživatel má přece uživatelské rozhraní, které samotné uživatele omezuje a hlídá. Navíc komunikaci tvaruje do nějakého protokolu tak, aby pro přijímací stanici bylo co nejjednodužší tomu porozumět. Uživatel má pak před sebou např výběrovou roletku, kde nemůže navolit nic jiného než mu dovolíme, tlačítka a přepínače.

tosik
Příspěvky: 71
Registrován: 11 led 2020, 14:48
Reputation: 0

Re: Kde mám chybu - switch

Příspěvek od tosik » 12 led 2020, 11:03

Díky za odpovědi a návrhy. Ono opravdu tady v tomto případě je asi zbytečné to ověřovat, sériová linka k dispozici nebude, ale učím se, a tak jsem si to chtěl trošku okořenit. Potřebuji praktický příklad, abych to pochopil. Ono se mi to časem v nějakém projektu bude hodit, až budu potřebovat něco odfiltrovat, zkontrolovat. Ještě jednou díky.

gilhad
Příspěvky: 508
Registrován: 07 bře 2018, 11:22
Reputation: 5

Re: Kde mám chybu - switch

Příspěvek od gilhad » 12 led 2020, 12:18

No nevim, ja seriovou linku pouzivam docela casto, ono je to vyrazne jednodussi a univerzalnejsi - kdyz to vyladim, tak ji pak muzou pouzivat i arduina proti sobe (a pak ty hlasky spis vypadaji nejak takto: "#ERROR 2: Syntax, line 256, char 3 = ',' is not number") a naopak prijeti vypada "#OK: value 12" pricemz se hleda "#xxx:" a podle toho se to zaridi, zbytek se bud zobrazi, nebo zahodi

tosik
Příspěvky: 71
Registrován: 11 led 2020, 14:48
Reputation: 0

Re: Kde mám chybu - switch

Příspěvek od tosik » 12 led 2020, 17:12

Asi ano, já ji zatím používám, abych nemusel furt nahrávat program do Arduina, když chci zjistit, co se stane, když změním nějakou hodnotu a taky pro výpis stavu proměnných apod. Tak snad se jednou dostanu do fáze, kdy budu řešit i věci, jak píšeš... :-D Díky moc za pomoc.

tosik
Příspěvky: 71
Registrován: 11 led 2020, 14:48
Reputation: 0

Re: Kde mám chybu - switch

Příspěvek od tosik » 19 led 2020, 18:01

Ahoj.
Prosím ještě o radu. Počítám timestamp (h, m,s). Když použiji špatný převod času na sekundy, hodiny nenásobím 3600, ale 360, tak výsledek je správný, vyhodí to počet sekund. Když použiju těch 3600, tak to vyhodí číslo ve stovkách milionů. Formát čísla i fce mám unsigned long.
Prosím tě, kde dělám chybu? A taky proč, když fce delaruji jako void, tak ji někdy nemůžu použít a IDE vyhodí chybu, je to i v tomhle případě.

Kód: Vybrat vše

#include <Wire.h>

// adresa časového modulu DS3231
#define DS3231_I2C_ADDRESS 0x68

void setup() {
  // put your setup code here, to run once:
Wire.begin();
Serial.begin(9600);


}

void loop() {
  // put your main code here, to run repeatedly:

  displayTime2(); // zobrazení aktuálního času - hh:mm:ss
Serial.println(TimestampSecond());
delay(3000);

}

//fce pro výpočet uplynulé doby od začátku dne (00:00 až půlnoc, např." 01:00 -- > 60) ------------
unsigned long TimestampSecond() {
  byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
  readDS3231time(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year); // načtení aktuálního času
  byte casSekundy = (second);
  byte casMinuty = (minute);
  byte casHodiny = (hour);
  unsigned long timeStampSecond = ((casHodiny * 60*60) + (casMinuty * 60) + casSekundy);
  
  Serial.print(casHodiny);
  Serial.print("/");
  Serial.print(casMinuty);
  Serial.print("/");
  Serial.println(casSekundy);
  Serial.print("Timestamp: ");
  Serial.println(timeStampSecond);
  Serial.println("--------------------------------------");
  return timeStampSecond;
  
}//-----------------------------------------------------------------------------------------

//fce pro čtení času z modulu DS3231----------------------------------------------------
void readDS3231time(byte *second, byte *minute, byte *hour, byte *dayOfWeek, 
                    byte *dayOfMonth, byte *month, byte *year) {
    Wire.beginTransmission(DS3231_I2C_ADDRESS);
      Wire.write(0); // set DS3231 register pointer to 00h
    Wire.endTransmission();
    Wire.requestFrom(DS3231_I2C_ADDRESS, 7);
    // chceme 7 bytů dat z registru v DS3231 začínajících na adrese 00h
    *second = bcdToDec(Wire.read() & 0x7f);
    *minute = bcdToDec(Wire.read());
    *hour = bcdToDec(Wire.read() & 0x3f);
    *dayOfWeek = bcdToDec(Wire.read());
    *dayOfMonth = bcdToDec(Wire.read());
    *month = bcdToDec(Wire.read());
    *year = bcdToDec(Wire.read());
    
}//--------------------------------------------------------------------------------------

//fce pro zobrazení času - jen hodiny, minuty a sekundy --------------------------------
void displayTime2() {
  byte second, minute, hour;
  // načtení dat z DS3231 fcí readDS3231time
  readDS3231time2(&second, &minute, &hour);

  // odeslání dat na sériový monitor
  Serial.print("<<");
  Serial.print(hour, DEC);
  Serial.print(":");

  if (minute < 10) {
    Serial.print("0");
  }
  Serial.print(minute, DEC);
  Serial.print(":");

  if (second < 10) {
    Serial.print("0");    
  }
  Serial.print(second, DEC);
  Serial.println(">>");
   
}//--------------------------------------------------------------------------------------

//fce pro čtení času z modulu DS3231 - jen hodiny, minuty a sekundy ----------------------------------
void readDS3231time2(byte *second, byte *minute, byte *hour) {
    Wire.beginTransmission(DS3231_I2C_ADDRESS);
      Wire.write(0); // set DS3231 register pointer to 00h
    Wire.endTransmission();
    Wire.requestFrom(DS3231_I2C_ADDRESS, 3);
    // chceme 3 bytů dat z registru v DS3231 začínajících na adrese 00h
    *second = bcdToDec(Wire.read() & 0x7f);
    *minute = bcdToDec(Wire.read());
    *hour = bcdToDec(Wire.read() & 0x3f);
        
}//--------------------------------------------------------------------------------------

// konverze z desítkové do dvojkové soustavy------------------------------------
byte decToBcd (byte val) {
  return((val/10*16) + (val%10));
}//------------------------------------------------------------------------------

// konverze z binární do desítkové-----------------------------------------------
byte bcdToDec (byte val) {
  return((val/16*10) + (val%16));
}//------------------------------------------------------------------------------

tosik
Příspěvky: 71
Registrován: 11 led 2020, 14:48
Reputation: 0

Re: Kde mám chybu - switch

Příspěvek od tosik » 19 led 2020, 18:44

Zkusil jsem v novém sketchi vypočítat toto:
long a = (18 * 60 * 30) -->>32400, pak toto
long a = (18 * 60 * 31) -->>-32056 ?? Přeteklo to. Jak to? Long by měl mít trošku větší rozsah, ne?

Pak toto:
unsigned long a = (18 * 60 * 30) -->>32400, a toto
unsigned long a = (18 * 60 * 31) -->>4294935240 ?? No mě z toho je***.

Co mám špatně?

Kód: Vybrat vše

void setup() {
  Serial.begin(9600);
  unsigned long a = (18 * 60 * 31);
  Serial.println(a);
}

void loop() {
  // put your main code here, to run repeatedly:

}

Odpovědět

Kdo je online

Uživatelé prohlížející si toto fórum: Žádní registrovaní uživatelé a 5 hostů