Skapa ett programvalsystem i C

C, C++, Pascal, Assembly, Raspberry, Java, Matlab, Python, BASIC, SQL, PHP, etc.
Användarvisningsbild
Icecap
Inlägg: 26106
Blev medlem: 10 januari 2005, 14:52:15
Ort: Aabenraa, Danmark

Re: Skapa ett programvalsystem i C

Inlägg av Icecap »

Jag tycker - som sodjan - att menysystemet inte ska vara den raketvetenskap som den verkar blåsas upp till.

Magnus_K: du vill alltså växla mellan olika funktioner så som intensiteten i några steg, blinka SOS, lokationsblinka (kort blink var 10 sek.) och lite annat småkrafs.

Som jag ser det är det en sak du inte verkar ha tänkt på:
Hur slår man på och av?

Om ett långt tryck under drift betyder "Gå i kommandoläge" kan du ju inte använda det tryck till att slå av. Eller jo - men då måste du ha två olika långa tryck: långt och mycket långt.

Jag hade nog vald t.ex. 3 snabba korta tryck för att komma i kommandoläge.

Men resten är mycket enkelt:
Du behöver en variabeln som anger vilken funktion som är aktiv just nu. Den kan såklart sparas i EEPROM och ska då kallas fram vid uppstart.

Resten hade jag gjort med en switch(Function) där de olika funktionerna fick var sin lilla programsnudd.
Ja, det sätt är uselt vid många punkter i en meny men till en lampa duger det riktigt fint.
Användarvisningsbild
sodjan
EF Sponsor
Inlägg: 43148
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping
Kontakt:

Re: Skapa ett programvalsystem i C

Inlägg av sodjan »

> Har du något exempel på enkelt menysystem du gjort. Eller vill förklara hur du gick till väga?

Nej, det har jag inte så det kan jag inte. Det jag (med flera) försöker säga är att
termen "menysystem" nog är lite för mycket sagt om det du vill uppnå. Du gör
det nog lite för svårt för dig, helt enkelt. Här handlar det bara om att följa ett
par logiska val. Några flaggor för att hålla reda på om man ligger i "val av program"
eller "val av steg i aktuellt program" och vilket program resp steg som för tillfället är valt.

Kanske någon timeout (30 sek?) ifall man bara avbryter inmatningen.
Användarvisningsbild
Icecap
Inlägg: 26106
Blev medlem: 10 januari 2005, 14:52:15
Ort: Aabenraa, Danmark

Re: Skapa ett programvalsystem i C

Inlägg av Icecap »

Magnus_K: Som alltid är det vettigt att skissa lite innan man börjar.
Du bör skriva ner vilka funktioner du vill uppnå, vilka knapptryckningar som ska fungera och gärna en liten tabell över tryckningar kontra punkter.

Om det finns något ologisk/kolliderande brukar det framgå ganska snabbt.

Du behöver sedan att ta fram en rutin för varje av:
* Ställ intensitet.
* Blink SOS i lagom hastighet.
* 10 sek blink.

Knapptryckningens längd kan man ganska enkelt kolla med en timer-interrupt (behövs ju för blinkningen också) och räkna på hur lång tid knappen är inne. Kollar man 10gg/sek räcker det, jag har testat detta. Men 20gg/sek är helt OK också.
Användarvisningsbild
Magnus_K
EF Sponsor
Inlägg: 5854
Blev medlem: 4 januari 2010, 17:53:25
Ort: Skogen mellan Uppsala-Gävle

Re: Skapa ett programvalsystem i C

Inlägg av Magnus_K »

datajompa:
Tack än en gång för tiden du lagt ner. Dock vill jag inte kopiera den koden och försöka använda för jag förstår inte mycket av den. Lite för hög nivå för mig.
Vad jag dock beslutat mig för att göra är att följa ditt/erat tips om att köra koden "torrt" i och använda printf() för att simulera. Tror jag kan få till något sånt på en hallopaj, i windows vet jag inte alls. Tack för det tipset!

Jag är väldigt säker på vilka funktioner jag vill ha, men jag kan nog inte presentera dom tydligt nog.
Icecap, jag har tänkt på AV kontra "inta programerringsläge". AV (dvs släckt och MCU:n i sleep) är ett tillstånd. Alltså vid varje knapptryck så är en funktion/tillstånd just AV.

Jag vet inte om det går att beskriva vad jag är ute efter. Det är inte att någon ska sitta och skriva kod åt mig utan bara ett tänkbart flöde till ett sånt här "system". Det ska till fler funktioner men det kommer lätt gå att läggas till när man fått till grunden enligt nedan beskrivning.

Ska försöka förklara mer ingående:

Hårdvara:
  • - MCU
    - Piezo-buzzer
    - Vit LED
    - Röd LED (bakåtriktad)
    - Knapp
Funktioner:
  • - Kort ljudsignal, används vid programbyte och ska mjukvaru-PWM:as med 1,5kHz
    - Lång ljudsignal, används vid batterivarning och ska mjukvaru-PWM:as med 1,5kHz
    - 100% Vit LED (helljus), hårdvaru-PWM
    - 50% Vit LED (halvljus), hårdvaru-PWM
    - Röd LED, används vid "cykelprogrammet" och ska mjukvaru-PWM:as med 20% DC och 2Hz
    - Knapptryck som mjukvaruavstudsas
Program 1 (Normal):
  • - Snabbt knapptryck skiftar mellan helljus, halvljus och AV.
    - Varning för låg batterinivå
Program 2 (Cykel):
  • - Snabbt knapptryck skiftar mellan helljus, halvljus och AV, dock så ska den röda LED:en samtidigt blinka i läge hel- och halv-ljus
    - Varning för låg batterinivå

Funktionen för tex Program 1 är då:
  • - MCU:n ligger i sleep och i läge AV.
    - Vid ett snabbt knapptryck så tänds den vita LED:en med 100% PWM.
    - Nästa knapptryck sänker PWM-nivån till 50%
    - Ytterligare ett knapptryck släcker LED:en och sätter MCU:n i sleep
    - Så länge MCU:n inte är i sleep så kollas batterispänning av var 5e sekund och varnar om man kommer förbi en tröskel.
    - För att ändra program så håller man inne knappen i ett antal sekunder tills man hör ett pip, därefter skiftar varje knapptryck Program och signalerar detta genom ett pip.
    - När rätt program är valt så håller man inne knappen i ett antal sekunder till man hör ett pip och det nya programmet är aktivt.
Jag vet inte om det går att beskriva vad jag är ute efter. Det är inte att någon ska sitta och skriva kod åt mig utan bara ett tänkbart flöde till ett sånt här "system". Det ska till fler funktioner men det kommer lätt gå att läggas till när man fått till grunden enligt ovan beskrivning.
Användarvisningsbild
hanpa
Utsparkad, på semester
Inlägg: 639
Blev medlem: 22 november 2016, 21:54:43
Ort: Hemort

Re: Skapa ett programvalsystem i C

Inlägg av hanpa »

Verkar fullt görbart men då du har väldigt specifika krav på 1.5kHz etc. så kan det bli olika svårt beroende på vilken plattform du har. Vad kör du på?

Att få till det är en sak men jag antar att du dessutom vill spara på batteriet.
Användarvisningsbild
Magnus_K
EF Sponsor
Inlägg: 5854
Blev medlem: 4 januari 2010, 17:53:25
Ort: Skogen mellan Uppsala-Gävle

Re: Skapa ett programvalsystem i C

Inlägg av Magnus_K »

Magnus_K skrev: Processorn är en PIC12F1840 (8 pin av storleksskäl och kan lätt drivas på neråt 3V av lipo-acken). När batterier sätts i så kommer avläsning från inbyggt flash ske för att se om tidigare program matats in. Om inte, så sätts ett "default" program och sedan går µC i sleep. När lampan stängs av så går också µC:n i sleep.
Varje gång ett nytt program sätts så sparas detta i flash/EEPROM.

Till en början så kalkylerar jag timers/interrupts etc med 8 MHz (intern klocka), men min tanke är att sänka denna så lågt som går, men vidhålla önskad PWM/timer tider. Detta är dock under "utveckling".
Sen är det lite kräm i lampan så att spara ström genom att snåla med processorn är lite överdrivet.
Lite osäker på just vad en plattform är men svarar det ovan din fråga?

Mjukvaru-PWM:ningen och knappavstuds är tänkt att lösas med interrupts. Jag har 3 timers att tillgå.
Användarvisningsbild
hanpa
Utsparkad, på semester
Inlägg: 639
Blev medlem: 22 november 2016, 21:54:43
Ort: Hemort

Re: Skapa ett programvalsystem i C

Inlägg av hanpa »

Sorry, tittade bland tidigare inlägg men såg inte detta. Det ser ju ut som att det bara är att köra på då med timers och interrupts. Du behöver ju hantera debounce och hålla reda på hur länge knappen är nedtryckt men i övrigt känns det som att att det går att göra det på lite olika sätt med tillståndsmaskin som du anropar i samband med olika events eller i en huvudloop som körs i lämplig frekvens. Du har bra koll på vad du vill göra och lite grand hur, känns som att det bara är att börja programmera.

Jag hade nog valt att göra en tillståndsmaskin som håller reda på vad som händer och vilken mod man är i för tillfället. Den kan man lämpligen göra som en separat rutin som anropas på lämpliga ställen. Den kan ju då starta timers när de ska dra igång och kanske även stoppa dem (om man inte gör det i resp. rutin som anropas då timern löser ut, efter ett visst antal varv eller liknande).

Antingen börjar du med tillståndsmaskinen för att få till alla övergångar, eller så börjar du med att få igång alla timers så att de kan utföra sitt jobb.
Eller tar det lite pö om pö om det är roligare.
datajompa
Inlägg: 232
Blev medlem: 5 november 2010, 10:35:54

Re: Skapa ett programvalsystem i C

Inlägg av datajompa »

Magnus_K skrev: Dock vill jag inte kopiera den koden och försöka använda för jag förstår inte mycket av den.
Kolla main så ser du att det är väldigt lite kod, det mesta är "data". Det är det som är finessen med att koda på det viset.
Magnus_K skrev:Vad jag dock beslutat mig för att göra är att följa ditt/erat tips om att köra koden "torrt" i och använda printf() för att simulera.
Om du vill simulera interrupter så kan jag rekommendera att använda ett spelbibliotek. SDL kanske funkar? Poängen är att det kan vara krångligt att få till koden för timerinterrupter och knapptryckningar på ett modernt OS, och spel-libben har redan gjort det svåra jobbet och brukar ha hyfsad dokumentation.
Användarvisningsbild
Magnus_K
EF Sponsor
Inlägg: 5854
Blev medlem: 4 januari 2010, 17:53:25
Ort: Skogen mellan Uppsala-Gävle

Re: Skapa ett programvalsystem i C

Inlägg av Magnus_K »

Ska kika närmare på det datajompa. Tror även jag har någon bok om just spelprogrammering som kanske kan hjälpa mig lite på traven till en bra simulering :tumupp:

Nedan är början på min kod. Eller ja, det tredje utkastet efter att ha skrotat bort ungefär hälften.
Är det här ungefär det ni menar med "state machine"?

Som ni ser så är jag harvar i steady() just nu men det är i det här skedet det börjar bli svettigt. Nu vill jag baka in det röda blinket men också med en sån struktur så denna funktion ska kunna väljas bort, och eventuellt andra funktioner läggas till.

EDIT: Uppdaterat koden till nuvarande status. Tror jag precis fick till spänningskollen av batteriet. Nästa attack blir att få till två olika långa summer-signaler men det är också nu det börjar koka i huvet...

Kod: Markera allt

uint8_t buttonStatus;
uint8_t pushRegistered;
uint16_t battcheckCounter;

enum processorStates {
   ERROR,
   RUNNING,
   GOTO_SLEEP,
   RECOVER
};

enum lampFunctions {
   OFF,
   LED_HIGH,
   LED_LOW
};

enum processorStates processorState = GOTO_SLEEP;
enum lampFunctions lampFunction = OFF;

/***********************************************************************/

void setSleep(){

   // <---- Set all outputs to inputs here
   FVRCON.FVREN = 0;               // Turn off Voltage reference
   VREGCON = 0x03;                 // Use low power sleep
   if(!buttonStatus){              // Only put to sleep when button has been released
     processorState = RECOVER;
     asm sleep;
   }
}

/***********************************************************************/

void recover_from_sleep(){

   uint8_t startupVoltage = 0;
   
   // <---- Restore all I/O:s here
   IOCAF.IOCAF3 = 0;               // Reset the IOC flag bit
   FVRCON.FVREN = 1;               // Enable Internal Voltage reference

   while(!FVRCON.FVRRDY){}
   
   startupVoltage = get_voltage();

   if(startupVoltage >= 190) {
      processorState = RUNNING;
   } else {
      processorState = ERROR;
   }
}

/***********************************************************************/

uint8_t get_voltage() {

   uint8_t voltage_level = 0;
   
   if(FVRCON.FVRRDY){
      voltage_level = ADRESH;
      ADCON0.GO = 1;
   } else {
      processorState = ERROR;
   }
   
   return voltage_level;
   
}

/***********************************************************************/

void battcheck(){

   uint8_t batt_level = 0;
   batt_level = get_voltage();
   
   // Check voltage each 2 minute. Decrease interval av make a buzz below 3,6V
   // (225 ADC value). Turn of LED and put lamp in ERROR state below 3V (187 ADC value))
   
   if(batt_level >= 226) {
      battcheckCounter = 0;                    // New battcheck every 2 min
   }
   else if((batt_level <= 225) && (batt_level >= 200)) {
      //make buzz
      battcheckCounter = 6000;                 // New battcheck and buzz every minute
   }
   else if((batt_level <= 199) && (batt_level >= 189)) {
      //make buzz
      battcheckCounter = 9000;                 // New battcheck and buzz every 30 sec
   }
   else if((batt_level <= 188) && (batt_level >= 187)) {
      //make buzz
      battcheckCounter = 11900;                // New battcheck and buzz every sec
   }
   else if(batt_level <= 186) {
      processorState = ERROR;
   }
}

/***********************************************************************/

void steady(){

   // Insert counter for voltage check here. If counter > 2 min, make buzz.


   if(buttonStatus && (!pushRegistered)){             // When button has been debounced
     pushRegistered = 1;                              // and not been registered yet then
                                                      // do the following.
     lampFunction = (lampFunction + 1);
     if(lampFunction >= 3){
        lampFunction = 0;
     }

     switch(lampFunction) {
          case OFF:
            processorState = GOTO_SLEEP;
            break;
          case LED_HIGH:
            // STARK LED FULL PWM
            if(12000 <= battcheckCounter) {           // 12000 = 10ms x 2 min
               battcheck();
            }
            break;
          case LED_LOW:
            // PWM på 50%
            if(12000 <= battcheckCounter) {           // 12000 = 10ms x 2 min
               battcheck();
            }
          default:
            processorState = ERROR;
            break;
     }
   }
}

/***********************************************************************/

void interrupt(){

   if(INTCON.TMR0IF) {                            // This interrupt occurs each 10ms
                                                  // and is only turned off in sleep
      static uint8_t debounceCounter;
      
      battcheckCounter++;

      INTCON.TMR0IF= 0;                           // Reset interruptflag
      TMR0 = 100;                                 // Pre-set timer value
      debounceCounter <<= 1;
      debounceCounter |= BUTTON;

      if (debounceCounter == 0x00) {              // Om byte:n endast innehåller 0:or
          buttonStatus = 1;                       // så sätt status till 1
      }
      else if (debounceCounter == 0x00) {         // Om byte:n endast innehåller 1:or
               buttonStatus = 0;                  // så sätt status till 0
               pushRegistered = 0;
      }
   }
   
   if(INTCON.TMR2IF) {                            // If enabled, this interrupt occurs
                                                  // with a freq of 2kHz
      INTCON.TMR2IF = 0;
      BUZZER = ~BUZZER;
   }
}

/***********************************************************************/

void main(void) {

   init();

   while(1){

     switch(processorState) {
        case ERROR:
          //warning();
          break;
        case RUNNING:
          steady();
          break;
        case GOTO_SLEEP:
          setSleep();
          break;
        case RECOVER:
          recover_from_sleep();
          break;
        default:
          //warning();
          break;
      }
   }
}
mounte
Inlägg: 204
Blev medlem: 14 november 2010, 13:15:00
Ort: Sandviken

Re: Skapa ett programvalsystem i C

Inlägg av mounte »

Som någon skrev några inlägg tidigare ... detta med menysystem borde inte vara så "rocket science"...
Menysystem finns det massor av bibliotek för att hantera. Om man vill komma igång fort och har ett projekt som kräver lite mer än bara "välj 1,2 eller 3" så kan det vara idé att kika om det finns något lib som löser problemet på ett trevligt sätt (har ett schysst api) samt att ens mikroprocessor rymmer det extra libbet.

Från arduino-världen finns en uppsjö och jag klistrar in en orankad lista nedan för framtida referens.
Listan hämtad från tråden: http://forum.arduino.cc/index.php?topic=131614.0

Library Name: LCDMenu2
Download: http://arduino.cc/forum/index.php/topic,73816.0.html

Library Name: LCDMenu
Download: http://arduino.cc/forum/index.php/topic,96104.0.html

Library Name: MenuBackend
Download: http://wiring.uniandes.edu.co/source/tr ... nuBackend/

Library Name: LCDMenu
Download: http://www.metalgecko.com/arduino/LCDMenu.zip (does not exist any more)

Library Name: Arduino_LCD_Menu
Download: https://github.com/DavidAndrews/Arduino_LCD_Menu

Library Name: MENWIZ
Download: https://github.com/brunialti/MENWIZ

Library Name: phi_prompt
Download: http://liudr.wordpress.com/libraries/phi_prompt/

Library Name: MenuSample
Download: http://sourceforge.net/projects/arduino ... enuSample/

Library Name: M2tklib
Download: http://code.google.com/p/m2tklib/

Library Name: OpenMoCo Menu Manager
Download: http://arduino.cc/forum/index.php/topic,131614.0.html, http://dynamicperception.com/software/o ... -libraries
Användarvisningsbild
hanpa
Utsparkad, på semester
Inlägg: 639
Blev medlem: 22 november 2016, 21:54:43
Ort: Hemort

Re: Skapa ett programvalsystem i C

Inlägg av hanpa »

Ingen av länkarna är väl relevanta för frågan eftersom menysystemet i detta fall inte har någon display alls utan bara möjligheter att blinka/pipa för att indikera menyval. Menyalternativen är alltså inte ens synliga utan man måste veta om vilka de är på förhand.

Jag har förresten en Petzl Nao som fungerar så. Där byter man läge med en knapp som man vrider för att aktivera, snabbt eller så håller man den en stund. Man kan programmera den via datorn också, för att ställa in vilka lägen man sen vill kunna växla mellan.

http://www.manualsdir.com/manuals/236915/petzl-nao.html
Användarvisningsbild
Magnus_K
EF Sponsor
Inlägg: 5854
Blev medlem: 4 januari 2010, 17:53:25
Ort: Skogen mellan Uppsala-Gävle

Re: Skapa ett programvalsystem i C

Inlägg av Magnus_K »

Nej jag får nog inse att det är för svårt att ta sånt här skriftligt. Det blir otroligt svåröverskådat för andra när man själv sitter "i det". Måste lära mig att det inte går att starta såna här trådar i ett forum.
Ska traggla vidare men till en början strunta i alla extrafunktioner och programbyten. Det får bli en annan gång.
Tack för hjälpen så här långt.

@hanpa:
Såg du hade redigerat ditt inlägg medan jag skrev det här. I stort är det något liknande jag vill göra, men att "programmen" redan ligger i "hjärnan".
Användarvisningsbild
sodjan
EF Sponsor
Inlägg: 43148
Blev medlem: 10 maj 2005, 16:29:20
Ort: Söderköping
Kontakt:

Re: Skapa ett programvalsystem i C

Inlägg av sodjan »

> Måste lära mig att det inte går att starta såna här trådar i ett forum.

Det ska du väl inte säga. Det är ju inte (bara) ditt fel att en del inlägg
inte är helt relevanta... :-) Men visst, det handlar också mycket om
terminologi. Jag tycker t.ex att "programbyte" kan vara lite missvisande.
Det är ju samma program du kör hela tiden och det finns bara ett program. :-)
"Sekvens", "blinkmönster" eller något kanske är tydligare. På samma sätt
så kanske även "menysystem" bidrog till att det svävade ut lite...

Om man går tillbaka till första inlägget så finns det ingen som helst ledtråd
till att det var en pannlampa, att det saknas normal display o.s.v. så det är
kanske förklarligt om tankarna först gick i den riktningen.
Användarvisningsbild
Magnus_K
EF Sponsor
Inlägg: 5854
Blev medlem: 4 januari 2010, 17:53:25
Ort: Skogen mellan Uppsala-Gävle

Re: Skapa ett programvalsystem i C

Inlägg av Magnus_K »

Det har du helt rätt i.
Omformulerar mig lite: Jag måste lära mig att jag inte kan skapa såna här trådar på ett forum.
Användarvisningsbild
Lennart Aspenryd
Tidigare Lasp
Inlägg: 12607
Blev medlem: 1 juli 2011, 19:09:09
Ort: Helsingborg

Re: Skapa ett programvalsystem i C

Inlägg av Lennart Aspenryd »

Nej Magnus
Sluta inte att fråga och att vara nyfiken.
Men träna på att beskriva ett flöde. Det kan vara genom ett scenario.
Detta är förutsättning !

En knapp finns och en krets som håller nästa knapptryckning klar för åtgärd.
Så betar man av de olika händelserna och när de kan inträffa.
Då kan man få hjälp att realisera sin dröm!
Skriv svar