• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Liutauras Vilda
  • Bear Bibeault
  • Junilu Lacar
  • Martin Vashko
Sheriffs:
  • Jeanne Boyarsky
  • Tim Cooke
  • Knute Snortum
Saloon Keepers:
  • Ron McLeod
  • Tim Moores
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
Bartenders:
  • Scott Selikoff
  • salvin francis
  • Piet Souris

Finite state machine or psuedo code for IR remote control flow?

 
Greenhorn
Posts: 3
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hello,

I'd like to preface this question with with what is working for me and to say I have been researching for a month
on how to solve my problem.  Any code I come up with isn't even close.  It just ends up being a convoluted mess.

I'm just looking for a little direction is all, in the form of pseudo code.

I'm working on a model of a spaceship that does various movements and lights and sounds based on ir remote button pushes.

I have set up a hypothetical problem so I can learn how to control several things with Arduino and it's code.

I have no issues with the hardware side.  I'm a very slow learner when it comes to code.

I figured out how to control 3 LED's with switch/case.  Pretty easy.  Each led turns of and on with three different remote buttons "independently".

Here's the code:




Works great.
 I can't for the life of me figure out the following problem:
 Red led is turned on/ off by button 1.
 Only when button one is "on", will control go to button two which turns yellow led on/off.
 Only when button two is "on", will control be allowed for button 3 to turn green led on/off.

Only when green is off will yellow be allowed to turn off/on.
Only when yellow is off will red be allowed to turn off/on.

The attached image shows three flow charts that kind of get my problem across but doesn't help me code correctly.
Each chart is saying the same thing in a different way.

I don't have any code that isn't just garbage.  I can't even post it.

If anyone can help me along solving this hypothetical problem, it would go a long way to help me with the actual project.

IRremote_control_flowcharts003.gif
[Thumbnail for IRremote_control_flowcharts003.gif]
 
Saloon Keeper
Posts: 21312
140
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I do these things in my sleep these days.

First, make sure that you are making a clear distinction between states, events, and actions. It seems common that people don't. A state is a stable condition. An event is something that happens that may trigger a state change. An action is something that you do. It may be done in direct response to an event or as part of the process of changing state.

So, speaking very abstractly and using a traffic light as an example, the light will have 3 possible states: green, yellow, and red. I'll ignore the other side of the light for now. It complicates things slightly and I'm going for simple.

So let's start out at red. Now we want to turn the light green to begin the cycle. That means changing the state from red to green and taking the actions of turning the red light off and the green light on. Now we're in the green state. Since this is an Arduino style loop, we can simply cycle through the loop, check for events, and return. Or wait. Or maybe sleep a while and return, thus re-entering the loop from the top.

Now the green timer expires. That's an event and we want to change state from green to yellow. Take the actions of turning the green light off and the yellow light on. And so forth.

My normal structure is that the loop() function has a state switch statement in it (and I use enums as states). When I want to change state, I call a newState() function, passing the next desired state as its argument. The newState() function is where I usually call action functions relating to leaving the old state and entering the new one. So actually, a green-to-yellow operation in newState would see that the new state was no longer green, but since the prior state was green, it would turn off the green light. I'd then set the current state to the new state value, and a switch statement for the new state would turn on the yellow light.

So in total, I'd have 3 switch statements. One in the main loop, where I monitor for events and, depending on what state I'm currently in, possible switch to a new state. Then in the newState method, there'd be a switch to handle leaving the old event, a statement changing the current state value, and a switch to fire actions related to the new state.

Details may vary depending on the application, but that's my general structure.
 
Russell Gillie
Greenhorn
Posts: 3
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Tim,
I compose music in my sleep.  But I'm not the sharpest knife in the drawer when it comes to coding.  I wonder if you could point me to an example code of what you are describing.
 
Sheriff
Posts: 24761
59
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

Russell Gillie wrote:I can't for the life of me figure out the following problem:
 Red led is turned on/ off by button 1.
 Only when button one is "on", will control go to button two which turns yellow led on/off.
 Only when button two is "on", will control be allowed for button 3 to turn green led on/off.

Only when green is off will yellow be allowed to turn off/on.
Only when yellow is off will red be allowed to turn off/on.



Maybe I don't understand the hardware you're working with, because I don't understand what it means for a button to be "on". I'm imagining a button where you press it, something happens, and then the button appears unchanged. Like a doorbell or a car horn. But I know that there are buttons which, when you press them they remain "pressed in" until you press them again and they pop out.

From your code it looks like your buttons are my naive car-horn buttons and not the buttons which stay pressed in until you press them again. If that's the case then your first problem is that the requirements are badly written. The phrase "when button one is on" needs to be rewritten in some way.
 
Russell Gillie
Greenhorn
Posts: 3
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Paul,
The buttons are codes received by an Arduino from a tv remote.  A finite state machine will do the trick, but it's not just push remote button 1 --do this.  It's almost like locking out previous and next states until conditions are met --but it's all about the remote button pushes.

Tim was getting what I was saying and I just hoped he could provide an example code of what he was talking about:

My normal structure is that the loop() function has a state switch statement in it (and I use enums as states). When I want to change state, I call a newState() function, passing the next desired state as its argument. The newState() function is where I usually call action functions relating to leaving the old state and entering the new one. So actually, a green-to-yellow operation in newState would see that the new state was no longer green, but since the prior state was green, it would turn off the green light. I'd then set the current state to the new state value, and a switch statement for the new state would turn on the yellow light.

So in total, I'd have 3 switch statements. One in the main loop, where I monitor for events and, depending on what state I'm currently in, possible switch to a new state. Then in the newState method, there'd be a switch to handle leaving the old event, a statement changing the current state value, and a switch to fire actions related to the new state.

 
Paul Clapham
Sheriff
Posts: 24761
59
Eclipse IDE Firefox Browser MySQL Database
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
TV remote, okay. So my guess was right, the buttons don't have any state. All of the state is in the model, which consists of three lights.

Which means that your task is to describe what happens to that state when you press one of the buttons. Right now your description of the problem is not all that helpful.

As for code examples, I think that it's too early for you to be writing code anyway. You need to get a better understanding of how to describe the problem. And seeing a code example isn't going to help you there.

For example: it looks to me like you have a basic rule which says "Pressing button 1 turns the red light on" -- no, sorry, it says "Pressing button 1 toggles the red light between off and on". But it also looks like there's a rule which says "The red light can only come on when the yellow light is off". I don't see a rule about what can happen to the red light when the yellow light is on.

So you're going to have a list of rules about when each light can go on and when it can go off. Then your action for each button is simply "Button 1 toggles the red light on/off when the rules allow that to happen" and so on. The main part of the design work is to describe those rules, which is the same as describing what changes of state can be made to the model. You've got a good start on that already.
 
Saloon Keeper
Posts: 10875
235
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I don't really see the problem if you know this can be done with a deterministic finite automaton.

There are n states, let us call them "phase 1" through "phase n".

State transitions occur because the DFA accepts a token that matches the label of a transition between the current state and a different state.

Let's say the current state is "phase 2". A token comes in that reads "button 3". This causes the DFA to transition from "phase 2" to "phase 3" because there is an arrow from "phase 2" to "phase 3" that reads "button 3".

Now, in "phase 3" a token "button 2" would do nothing, while a token "button 3" would cause a transition back to "phase 2".

Transitions can also be associated with actions. When a transition occurs, it triggers its associated actions. A transition from "phase 2" to "phase 3" might cause the green LED to switch on, while a transition from "phase 2" to "phase 1" might cause the yellow LED to switch off.

What you need to do is model a DFA by keeping track what possible states it can be in, what current state it's in, what transitions may occur for each state, and what actions are associated with each transition.

I can't be bothered to write C right now, but in Java it could look roughly like this:
 
Tim Holloway
Saloon Keeper
Posts: 21312
140
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Just to go back and re-inforce what was just said, buttons create events.  In the case of an infra-red remote control, pressing and holding  down a button will create/send a "press" event in response to the finger-pushed-button event. As long as the button is in the held-down state, often further press events will be sent (like on a volume-control button), but that depends on the control and the button. Releasing the button may also send an infrared message event in response to the finger-released-button event.

Now actually, it's possible to press down multiple buttons at one time ("chords") or to roll from one button to another (pressing the second before the first is released). But most remotes won't support that as a deliberate action and may therefore not send infrared message events in response to the extra keypresses. The remote has its own finite-state-machine built into its circuitry.
 
It will give me the powers of the gods. Not bad for a tiny ad:
Java file APIs (DOC, XLS, PDF, and many more)
https://products.aspose.com/total/java
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!