I am preparing a little program for a new project in wich I use a simple program architecture with a State Machine.
Checking the pressure of a button to ground on a pin, doing it in the main Do-Loop before entering the Select Case block of the State Machine, I can cycle trough 1 to 5 states without problem..
But if I want to check the pin condition WHITIN one of the states, in order to move from one state to another, the button pressure gets ignored..
I made several tests, but I am still stuck because of this at the very beginning of the development.
I think you have an error in the display of the state.
Try
Do' 1. Handle Button Inputs & State Transitions independently Select Case stato case 1 'AttesainputUtenteRiga1=" Press Start to "Riga2=" make a Measure "ifStart_Btn=0thenwait100mS'debounce if Start_Btn = 0 then Wait Until Start_Btn = 1 stato = 2 end If end if case 2 Riga1 = "This is State 2" Riga2 = "press to go 3rd!" 'Addyourbuttoncheckheretoadvancetostate3!ifStart_Btn=0thenwait100mSifStart_Btn=0thenWaitUntilStart_Btn=1stato=3endIfendifcase3Riga1="This is State 3"Riga2="press to go 4th!"ifStart_Btn=0thenwait100mSifStart_Btn=0thenWaitUntilStart_Btn=1stato=4endIfendifcase4Riga1="This is State 4"Riga2="press to 1st!"//or5ifStart_Btn=0thenwait100mSifStart_Btn=0thenWaitUntilStart_Btn=1stato=1' Cycle back or go to 5 end If end if case 5 Riga1 = "Error ! Shutdown" Riga2 = "System & Restart" StartTimer 1 if Timer_Steps = 15 Then Led_diagnostico = Not Led_diagnostico Timer_Steps = 0 ClearTimer 1 end If end select '2.Displayrefreshmanagedstrictlyonstatechangeifstato_precedente<>statothenclsPrintRiga1Locate1,0PrintRiga2stato_precedente=statoEndif'3.DiagnosticLEDcleanupifstato<>5thenLed_diagnostico=0Loop
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
However, I can't see the difference in respect to my code. It does'nt matter (for the moment) to add more button checks into the other states. The cycling was made only to begin the development, during the final version states may change on different criteria..
The problem is that this block here is completely ignored:
(whitin State=1)
if Start_Btn = 0 then
wait 100 mS 'debounce
if Start_Btn = 0 then
Wait Until Start_Btn = 1
stato = 2
end If
end if
I found an error of mine in not disabling the analog inputs on port A that I tought could be the problem, so I changed my previous line (acting only on B port) as follows:
from:
ADCON1 = 0x0F
to:
ANSEL = 0
ANSELH = 0 ' should disable analog on both portA & portB
Hoping this was the issue, but the problem is the same. Test on button made outside the Select Case block works, inside one of the Case x does not..
Can't really thing of anything else happening.. ?!?
Should the "Case Else" statement addition mandatory to have the Select Case working?
Might it be possible that multiple if/then blocks nested whitin a Do-loop that contains a Select Case etc.. creates some reentrance prolems with this small uCtr?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
The ports are disabled automatically. so that is is not the issue.
This is logic code not the state of the port. I have refactored so the logic makes sense to me.
It works here.
Evan
' =====================================================================' CONFIGURAZIONE DEL CHIP E DELLE PERIFERICHE' =====================================================================#Chip 16F886, 8 ' Imposta il microcontrollore a 8 MHz#config FOSC = HS ' utilizza il quarzo esterno' =====================================================================' CONFIGURAZIONE DEL DISPLAY LCD (Modalit� 4-bit)' =====================================================================#Define LCD_IO 4'linee valide per Protoboard, cambiare in#Define LCD_Enable PORTA.0 '#Define LCD_Enable PORTA.2 nel PCB finale#Define LCD_RW PORTA.1 #Define LCD_RS PORTA.2 '#Define LCD_RS PORTA.0 nel PCB finale#Define LCD_DB4 PORTB.4#Define LCD_DB5 PORTB.5#Define LCD_DB6 PORTB.6#Define LCD_DB7 PORTB.7' =====================================================================' CONFIGURAZIONE Altre Costanti' =====================================================================#Define On = 1 'costanti per chiarire i valori assegnati ai flag, Pin I/O e variabili#Define Off = 0#Define Start_Btn PORTA.4 'Pulsante Utente per avviare le misure#Define Led_diagnostico PORTC.3 'Uscita led lampeggiante per Diagnostica Programma' =====================================================================' DICHIARAZIONE DELLE VARIABILI' =====================================================================DimstatoasByte'identificatore dello stato macchinaDimstato_precedenteasByte'per decidere se effettuare refresh display senza sfarfallio DimTimer_StepsasByte'numero di overflows del Timer1DimRiga1asstring(16)'contiene buffer 1a riga displayDimRiga2asstring(16)'contiene buffer 2a riga displayDimdebug=1' =====================================================================' CONFIGURAZIONE HARDWARE' =====================================================================DirPORTB.0In' RB0 (INT0) come ingresso su cui misurare l'impulsoADCON1=0x0F' Disabilita i convertitori A/D su PORTBDirPORTC.3out' uscita per Led diagnosticoDirPortA.4in' pulsante Utente' Configura il Timer1 (Incremento ogni 1/2 microsecondo)InitTimer1Osc,PS1_1StopTimer1ClearTimer1' =====================================================================' CONFIGURAZIONE INTERRUPT' ====================================================================='gestione interrupt per overflow Timer1OninterruptTimer1OverflowcallIncrementa_Timer_StepsPrint"Started"' =====================================================================' Avvio Programma, eseguito solo all'accensione' ====================================================================='inizializza statistato=1stato_precedente=0' =====================================================================' CICLO PRINCIPALE della macchina a stati' =====================================================================Do'***** This commented block down here works when a pushbutton is pressed to ground on a 10K Ohm pull-upped PORTA.4' and cycles to the various states without problems/*'se premo il pulsante passa allo stato successivoifStart_Btn=0thenwait100mS'debounceifStart_Btn=0then'Attesa rilascio pulsante per evitare passaggi di stato multipliWaitUntilStart_Btn=1stato++endIfifstato=6thenstato=1endif*/Locate2,0PrintstatoLocate3,0Printleftpad(Str(debug),3," ")debug++SelectCaseStatocase1'Attesa input Utente per avviare una Misura Riga1=" Press Start to "Riga2=" make a Measure "'************ The same condition checked here whitin one state gets ignored!'*** Hardware is ok, using the condition on the above mentioned block'*** outside the states, everything goeas as expected.. Why?? ShowLCDwaitforbtnstato=2case2Riga1="This is State 2"Riga2="press to go 3rd!"stato_precedente=0ShowLCDwaitforbtnstato=3'later on more codecase3'in questo stato si determina la durata del tempo in microsecondiRiga1="This is State 3"Riga2="press to go 4th!"stato_precedente=0ShowLCDwaitforbtnstato=4'later on more codecase4Riga1="This is State 4"Riga2="press to 5th!"stato_precedente=0ShowLCDwaitforbtnstato=5'later on more codecase5'solo lampeggio Led su porta C3 , ad uso diagnostico programma'segnala errore e fa lampeggiare LedRiga1="Error ! Shutdown"Riga2="System & Restart"stato_precedente=0ShowLCDwaitforbtnStartTimer1'avvia il timer. Se gi� attivo, non viene resettato il conteggioifTimer_Steps=15ThenLed_diagnostico=NotLed_diagnostico'inverto polarit�Timer_Steps=0'riazzero timerClearTimer1'se ci sono stati 15 Overflows del Timer1, il'led commuta ogni 0,49152 secondi - circa 2.032 HzendIfendselect'Per evitare che resti acceso il led blinker se non necessarioifstato<>5thenLed_diagnostico=0LoopSubShowLCD'gestione aggiornamento displayifstato_precedente<>statothenclsPrintRiga1Locate1,0PrintRiga2stato_precedente=stato'necessario per evitare 'flickering' del dispalyWait100msEndifEndSub' =====================================================================' Gestione Interrupt da Timer1 Overflow' =====================================================================SubIncrementa_Timer_StepsTimer_Steps++' Timer_Steps +1EndSubSubWaitforBtn'se premo il pulsante passa allo stato successivo'di gestione interrupt impulso ifStart_Btn=0thenwait100mS'debounceifStart_Btn=0then'Attesa rilascio pulsante per evitare passaggi di stato multipliWaitUntilStart_Btn=1endIfendifEndSub
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Thanks for yr answer.. I made additional tests.
Your code for some reasons gives me errors, starting as soon as the row "Dim debug = 1".. And others..
I reduced my code to the bare minum of two states, and in this case it works( see test1.gcb attached). But as soon as more "case is" block get added, I find troubles.
Therefore I decided to abandon the Select Case approach e moved to a series of "if state is.." and my code works fine.
Finally, I improved the display refresh method and also the pushbutton detection, making it a function callable from any state - and it works ok. See test2.gcb).
I am not sure, but perhaps there is something stange in the Select Case -Case is structure.
I apologize if I cast a doubt on the Select Case correct working..
I persisted a while with some tests and found my error being in the need to prepare the new text and display refresh flag at the moment of leaving the present state and moving to the following one..
Now the sequence is correct, and the flow and readability of the program been improved with Select Case, a subroutine for LCD refresh and a Function for the button pressed test. Attached a working version of this prime stage. Sorry having bothered.
Answering yr last post:
So, there is an updated version of the compiler coming, great news. Is there any thinking about a debugger (even a limited one) that might permit to pause the program and look at the variables/registers etc on fly? That would makemuch speedier the development with GC Basic.
Thanks for the great work, and regards.
Hi there,
I am preparing a little program for a new project in wich I use a simple program architecture with a State Machine.
Checking the pressure of a button to ground on a pin, doing it in the main Do-Loop before entering the Select Case block of the State Machine, I can cycle trough 1 to 5 states without problem..
But if I want to check the pin condition WHITIN one of the states, in order to move from one state to another, the button pressure gets ignored..
I made several tests, but I am still stuck because of this at the very beginning of the development.
Any suggestion? Thanks!
I think you have an error in the display of the state.
Try
Thanks for your answer, Evan..
However, I can't see the difference in respect to my code. It does'nt matter (for the moment) to add more button checks into the other states. The cycling was made only to begin the development, during the final version states may change on different criteria..
The problem is that this block here is completely ignored:
(whitin State=1)
if Start_Btn = 0 then
wait 100 mS 'debounce
if Start_Btn = 0 then
Wait Until Start_Btn = 1
stato = 2
end If
end if
I found an error of mine in not disabling the analog inputs on port A that I tought could be the problem, so I changed my previous line (acting only on B port) as follows:
from:
ADCON1 = 0x0F
to:
ANSEL = 0
ANSELH = 0 ' should disable analog on both portA & portB
Hoping this was the issue, but the problem is the same. Test on button made outside the Select Case block works, inside one of the Case x does not..
Can't really thing of anything else happening.. ?!?
Should the "Case Else" statement addition mandatory to have the Select Case working?
updated file attached for reference
Might it be possible that multiple if/then blocks nested whitin a Do-loop that contains a Select Case etc.. creates some reentrance prolems with this small uCtr?
The ports are disabled automatically. so that is is not the issue.
This is logic code not the state of the port. I have refactored so the logic makes sense to me.
It works here.
Evan
Thanks for yr answer.. I made additional tests.
Your code for some reasons gives me errors, starting as soon as the row "Dim debug = 1".. And others..
I reduced my code to the bare minum of two states, and in this case it works( see test1.gcb attached). But as soon as more "case is" block get added, I find troubles.
Therefore I decided to abandon the Select Case approach e moved to a series of "if state is.." and my code works fine.
Finally, I improved the display refresh method and also the pushbutton detection, making it a function callable from any state - and it works ok. See test2.gcb).
I am not sure, but perhaps there is something stange in the Select Case -Case is structure.
Thanks for yr help given, I appreciated it.
There was/is nothing wrong with Case. :-) This is logic issue.
You have a method that works. And, this is a good result for you.
Good news. All working.
I am using the new compiler and you can now assign a value to a variable when you DIMension it.
Last edit: Anobium 5 days ago
I apologize if I cast a doubt on the Select Case correct working..
I persisted a while with some tests and found my error being in the need to prepare the new text and display refresh flag at the moment of leaving the present state and moving to the following one..
Now the sequence is correct, and the flow and readability of the program been improved with Select Case, a subroutine for LCD refresh and a Function for the button pressed test. Attached a working version of this prime stage. Sorry having bothered.
Answering yr last post:
So, there is an updated version of the compiler coming, great news. Is there any thinking about a debugger (even a limited one) that might permit to pause the program and look at the variables/registers etc on fly? That would makemuch speedier the development with GC Basic.
Thanks for the great work, and regards.
No problem with CASE. I am just grumpy at the moment. :-)
And, no problem with you asking. Sometimes just sharing helps. :-)
The new code looks good. :-)
There is a new version on the toolchain and compiler. We are close to a release.
There is a new debugger. See the picture. Yes, your code in the GCODE Debuuger!
Soon!
Evan