Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 22:10 02 Aug 2025 Privacy Policy
Jump to

Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.

Forum Index : Microcontroller and PC projects : uMite + Parallax Hackable Badge

     Page 3 of 4    
Author Message
dasyar
Regular Member

Joined: 13/04/2015
Location: United States
Posts: 58
Posted: 01:47am 13 Dec 2015
Copy link to clipboard 
Print this post

Thanks TassyJim, I will see if I can work it in to my UI program with a built in example. Now, I want to make sure that I have a good example of a UI working program that has a very reliable comm aspect with whatever kind of unit is attached to the uMite for comms.

I have given up on serial IR with the uMite, which leaves me with SIRC protocol control. I am very sure that I can get my Parallax Hackable Badge (HB) to work with SIRC. The HB has 7 buttons, and IR, plus a functional IR driver, so a quick and dirty remote controller could be accomplished? Oh no, can I put together a uMite robot and have remote IR control? That is another thread.

Thinking about the DH22, Dallas One-Wire, module, I doubt that you could use the One-Wire buss aspect, as the commands list is now, but it could be interesting to put more than one module in line on one pin, I think that is the way One-Wire works? Since the 28 pin uMite chip has a limited amount of IO pins, that could of been a way using that feature.

Now back to the UI program, more clean up and real time testing.
 
dasyar
Regular Member

Joined: 13/04/2015
Location: United States
Posts: 58
Posted: 09:35am 15 Dec 2015
Copy link to clipboard 
Print this post

I just did a little clean up on my breadboard, that holds the uMite, and I added an IR demodulator (receiver).

The program below compiles, and sort of works as expected. The part that is not working as expected is, when I press 'key' 1, the LED does not go off. Not sure why this is happening. When the program starts, pressing 'key' 0, turns the LED on. I am going by what the program was showing as a KeyCode.

I also tried putting the on/off IF loop in the main DO ... LOOP. When the program starts, the LED goes on, without any key press. I guess I need a little insight as to how this interrupt is working, and how I can work with a key press control from the main DO ... LOOP.

Just looking at my code I noticed that I should probably be using 'KeyCode' and not 'key'.


' testIR
' December 15, 2015

IR DevCode, KeyCode, IR_Int

SETPIN 17, DOUT

DO


LOOP


IR_Int:
PRINT "Received device = " DevCode " key = " KeyCode
IF key = 0 then ' If key 0 is pressed, LED on
PIN(17) = 1
elseif key = 1 then ' If key 1 is pressed, LED off
PIN(17) = 0
ENDIF
IRETURN
 
TassyJim

Guru

Joined: 07/08/2011
Location: Australia
Posts: 6283
Posted: 10:10am 15 Dec 2015
Copy link to clipboard 
Print this post

Variable 'key' is always zero.

Change key to KeyCode

' testIR
' December 15, 2015

IR DevCode, KeyCode, IR_Int

SETPIN 17, DOUT

DO


LOOP


IR_Int:
PRINT "Received device = " DevCode " key = " KeyCode
IF KeyCode = 0 then ' If key 0 is pressed, LED on
PIN(17) = 1
elseif KeyCode = 1 then ' If key 1 is pressed, LED off
PIN(17) = 0
ENDIF
IRETURN


Jim
VK7JH
MMedit
 
dasyar
Regular Member

Joined: 13/04/2015
Location: United States
Posts: 58
Posted: 11:29am 15 Dec 2015
Copy link to clipboard 
Print this post

The code below works as expected. My assumption is that the DO ... LOOP checks to see if there was some IR signal, if so, then it goes to the processing routine.

I know I had an IR LED, which now I cannot find, that will probably be the next thing I try out. Also I will have to set up some code on my Parallax Hackable Badge, and see what I can do with that, if anything interesting.

Since I also tried some different remotes that I have, I noticed not all of them were Sony code. I wonder if you could add some code that would print out something like a "Non Sony device", when the non Sony device was used?


' testIR
' December 15, 2015

' Start the IR interrupt
IR DevCode, KeyCode, IR_Int
' Setup pin 17
SETPIN 17, DOUT

DO
' Check if anything on IR
if KeyCode => 0 then
gosub IRprocess
endif

LOOP

END

' IR interrupt
IR_Int:
PRINT "Received device = " DevCode " key = " KeyCode
' IF KeyCode = 0 then ' If key 0 is pressed, LED on
' PIN(17) = 1
' elseif KeyCode = 1 then ' If key 1 is pressed, LED off
' PIN(17) = 0
' ENDIF
IRETURN

' Process the IR incoming code.
IRprocess:
IF KeyCode = 0 then
PIN(17) = 1 '' LED on
ELSEIF KeyCode = 1 then
PIN(17) = 0 '' LED off
ENDIF
return
 
disco4now

Guru

Joined: 18/12/2014
Location: Australia
Posts: 1003
Posted: 12:08pm 15 Dec 2015
Copy link to clipboard 
Print this post

Hi dasyar,

The last code you have sort of undoes the good work of using an interrupt. The code posted by Jim does what is required.

Think of interrupts as telling you when they want you to do something. You just set them up and they will tell you if you need to do anything.

This bit of code has your MM full time looking to see if the IR has anything, when it should be free to do other things if required.

DO
' Check if anything on IR
if KeyCode => 0 then
gosub IRprocess
endif

LOOP


The reason the DO :LOOP has nothing in it in Jim's code, is that the MM has nothing else to do and just sits in this loop forever. It will only do the IR stuff if the the IR puts its hand up for attention (interrupt).

Regards
Gerry


Latest F4 Latest H7 FotS
 
dasyar
Regular Member

Joined: 13/04/2015
Location: United States
Posts: 58
Posted: 02:03am 16 Dec 2015
Copy link to clipboard 
Print this post

Thanks disco4now, I fully realize that. To get a better grasp on this interrupt stuff, which one has priority one?

So far I have worked with COM:2 interrupt, a tick Interrupt, now the IR interrupt. I am going to be implementing something on the COM:1 interrupt. Lets say you have data coming in on all the interrupts, who gets dealt with first, and do one of the COM ports start to lose incoming data, at some point?

As for the IR receiver, I guess the only way you can access it, is with an interrupt setup, correct. Now, if you wanted to use an IR receiver and sender, other than using it for Sony codes, is there a way of doing that, and is there example code available?

Last night I did try using the HB with the uMite IR, as expected, the two did not want to talk. I think there is some code for the HB to send NEC codes, I am assuming that is compatible with Sony codes. I am still determined to get the HB and the uMite to talk to each other via the IR, I just do not know what that method will be.
 
MicroBlocks

Guru

Joined: 12/05/2012
Location: Thailand
Posts: 2209
Posted: 06:43am 16 Dec 2015
Copy link to clipboard 
Print this post

I use a simple rule to determine if the handling is done inside the interrupt routine or if it is stored in a buffer and a main loop processes it.

I only put processing inside an interrupt routine when it is VERY time critical or when it is reasonable time critical AND processing takes very little time.

All other cases i just buffer all incoming data and process it from main with polling mechanism and/or state machine.

If the sequence is important then you could store all incoming data as a string (i like CSV format) in a large array with a header that tells what kind of message it is and then process them in sequence from main.

Large amounts could be even stored on an SD card and processed from there. Lots of possibilities.

Look into (google) some samples of a producer/store/consumer pattern. That is a particular good pattern to work with when receiving data using interrupts.




Microblocks. Build with logic.
 
dasyar
Regular Member

Joined: 13/04/2015
Location: United States
Posts: 58
Posted: 02:37am 17 Dec 2015
Copy link to clipboard 
Print this post

Well, I got a crazy idea today as to how I could maybe use the uMite IR to send and receive characters.

The basis, assign characters to the Sony code and then have MMbasic, using a sub or a function, interpret the code to form a string, boy does that sound easy. There would probably be a very long CASE statement, not sure how much memory that would be using. So would uMite be up to the task to do something like this? Is this feasible?

Or is there a better way, using the existing things that are available?
 
JohnS
Guru

Joined: 18/11/2011
Location: United Kingdom
Posts: 4044
Posted: 03:24am 17 Dec 2015
Copy link to clipboard 
Print this post

It sounds not to need a long CASE statement unless you're going to input a vast number of different codes. You're not going to do so are you?

John
 
dasyar
Regular Member

Joined: 13/04/2015
Location: United States
Posts: 58
Posted: 03:52am 17 Dec 2015
Copy link to clipboard 
Print this post

  Quote  
...input a vast number of different codes. You're not going to do so are you?

Well, I was thinking...

There already is 0 - 9, for 1 - 0 chars. I was thinking about assigning 16 - 67 for the alphabet, upper and lower case. Then have 68 - 99 for all the other characters like period, question mark, and such, while 99 would be eol. So, I am not sure if that would qualify as a vast number.

Using this scheme, I wonder if uMite would be very slow in responding, in a reasonable fashion. Of course the program would be doing other things also, like maybe offloading the incoming data to the RPi to deal with the data, in a chosen manner.
 
dasyar
Regular Member

Joined: 13/04/2015
Location: United States
Posts: 58
Posted: 01:13pm 18 Dec 2015
Copy link to clipboard 
Print this post

So I did quick code hack on the HB to send Sony code via IR, and I did an experiment to see what code, if any, the uMite would receive.

I had the HB send 0 - 99, to see if the uMite would receive all the numbers, which it did. No gaps, no missing numbers, looks like it's working.

Now, the hard part, I have to figure out what the next step, code wise is, for the uMite. I guess I should try to buffer the incoming code in some manner so that the captured code can be extracted and worked on? I am not sure what the best way is. The next step after this would be to do the interpretation of the code to its character values that would form readable strings. Anybody have any suggestions as what the best approach for this should be?
 
dasyar
Regular Member

Joined: 13/04/2015
Location: United States
Posts: 58
Posted: 03:41am 19 Dec 2015
Copy link to clipboard 
Print this post

Here is my first attempt at capturing the KeyCode, an integer, and placing it into an array, grabIR.

I am getting an error: 'number of dimensions' for 'grabIR = grabIR + Keycode'. Should grabIR be grabIR()? I think this array business is working a bit differently then what I think it should be, at least my interpretation.

Now if this were to work, how would I get the individual code numbers out to run it through an interpreter? I guess something like RIGHT$() will not work, grabIR array will have integers. I did not see any functions for converting an integer to a string char. What am I missing here?


' testIR
' December 15, 2015

' Start the IR interrupt
IR DevCode, KeyCode, IR_Int
' Setup pin 17
SETPIN 17, DOUT

DO


LOOP

END


IR_Int:
PRINT "Received device = " DevCode " key = " KeyCode
IF KeyCode = 0 then ' If key 0 is pressed, LED on
PIN(17) = 1
elseif KeyCode = 1 then ' If key 1 is pressed, LED off
PIN(17) = 0
ENDIF
DIM integer grabIR(20) ' Make grabIR an array
grabIR = grabIR + Keycode ' Add a KeyCode to the array
if KeyCode = 99 then ' This is eol
ShowIt
ENDif
IRETURN

SUB ShowIt
PRINT grabIR ' Print the array of numbers
END SUB
 
BobD

Guru

Joined: 07/12/2011
Location: Australia
Posts: 935
Posted: 08:30am 19 Dec 2015
Copy link to clipboard 
Print this post

Each element of an array must be addressed explicitly. Given your array declaration above then the following is not valid.
[code]grabIR=grabIR + Keycode [/code]
This is valid when x is an integer and is in the range of 0 to 20 which is the range of your array declaration
[code]grabIR(x)=grabIR(x) + Keycode [/code]
This is also valid
grabIR(x) = Keycode

If you wish to load Keycode into successive locations in the array then you could do a FOR ... NEXT loop
[code]FOR x = 0 to 20
grabIR(x)=Keycode
NEXT x[/code]
Print the array without any formatting of the print
[code]FOR x = 0 to 20
PRINT grabIR(x)
NEXT x[/code]
This doesn't directly help you with your program. It just shows what you can do with arrays.

Bob


Edited by BobD 2015-12-20
 
dasyar
Regular Member

Joined: 13/04/2015
Location: United States
Posts: 58
Posted: 11:58am 19 Dec 2015
Copy link to clipboard 
Print this post

I do not think that I am making any headway with this. This runs without errors, but my showIt is not working as expected.

It shows a row of zeros for the elements, except for one which it shows a 6. I was expecting the elements to be the KeyCode values that came in. Hmmm ...

This starting to feel like I am pulling teeth.



' testInc
' December 19, 2015

' Start the IR interrupt
IR DevCode, KeyCode, IR_Int

DIM x = 0

DO

LOOP



END

IR_Int:
DIM grabIR(20) ' Global
PRINT "Received device = " DevCode " key = " KeyCode


Print "x = " x
x = x + 1 ' Increment x
grabIR(x) = KeyCode ' KeyCode with specified element
Print grabIR(x) ' Print the variable with specific element

if KeyCode = 99 then ' If eol
showIt(grabIR(x))
endif
IRETURN

SUB showIt(x)
For x = 0 to 20 ' Start with first element of grabIR()
Print grabIR(x); ' Print all the elements
next x
END SUB
 
matherp
Guru

Joined: 11/12/2012
Location: United Kingdom
Posts: 10315
Posted: 12:44pm 19 Dec 2015
Copy link to clipboard 
Print this post

You are declaring a global variable in a subroutine

"DIM grabIR(20) ' Global "

In my view this should give an error as at each subsequent entry it is already defined

Only use DIM in the main program.

If you need local storage in a subroutine use "LOCAL" but remember this is not preserved between calls.

I don't know if this is your problem but it is definitely bad practice except in the special case of an initialisation subroutine that is only called once.
 
dasyar
Regular Member

Joined: 13/04/2015
Location: United States
Posts: 58
Posted: 02:24am 20 Dec 2015
Copy link to clipboard 
Print this post

Moving the 'DIM' out of the IR_Int SUB fixed it, Thanks matherp.

The program now works as expected, for the Proof-Of-Concept. I am using a one dimension element declaration, not sure how I would use a multi-dimensional element variable.

Basically the HB sends some IR code to the uMite, uMite captures the code, and then interprets the elements. I have declared the 'grabIR()' variable to have 21 elements, although I will increase this to maybe 40, but not sure how big of a buffer I need.

I guess the next step is to convert grabIR() from an integer based variable to an interpreted string based variable. The important part is to have a string based variable so then I can use the string manipulation functions that are available.

Lots of pain, but I am making some headway.


' testInc
' December 19, 2015

' Global
DIM grabIR(20)
DIM y
DIM x = 0
''''''''''

' Start the IR interrupt
IR DevCode, KeyCode, IR_Int


' Main program body
DO

LOOP

END
''''''''''

' The sub for the IR interrupt
IR_Int:
' Show actual of incoming
PRINT "Received device = " DevCode " key = " KeyCode

Print "x = " x
x = x + 1 ' Increment x
y = x - 1 ' Last increment before eol
grabIR(x) = KeyCode ' KeyCode for specified elemnt
Print grabIR(x) ' Print the value with the specific element

if KeyCode = 99 then ' If eol
showIt(grabIR(x)) ' Show individual elements
showIt2 ' Show the interpreted elements
endif
IRETURN
''''''''''

SUB showIt(x)
'For x = 0 to 20
For x = 1 to y ' Start with first element of grabIR()
Print grabIR(x); ' Print all the elements
next x
END SUB

''''''''''

' The interpreter sub
' Show the contents of grabIR(x) interpreted
SUB ShowIt2
For x = 1 to y
'PRINT grabIR ' Print the array of numbers
SELECT CASE grabIR(x)
CASE 43
PRINT "H";

CASE 14
PRINT "e";

CASE 21
PRINT "l";

CASE 24
PRINT "o";

CASE 99
PRINT ";"

END SELECT
Next x

END SUB
''''''''''
 
dasyar
Regular Member

Joined: 13/04/2015
Location: United States
Posts: 58
Posted: 11:37am 20 Dec 2015
Copy link to clipboard 
Print this post

An update: I sort of made it convert the incoming code to a string variable, now what do I do with the data. Since I am using a uMite with MMbasic 4.6, I guess attaching an SD module is out of the question. The other option, I guess is to setup comm with the RPi and have that deal with the data.

So, I guess the method would be, capture the incoming IR, convert it to a string and have it moved out the comm to the RPi, which would store it in a temp file. Then have a program on the RPi work the temp file to what I could use. Does that sound about right?


 
Geoffg

Guru

Joined: 06/06/2011
Location: Australia
Posts: 3292
Posted: 01:34pm 20 Dec 2015
Copy link to clipboard 
Print this post

  matherp said   You are declaring a global variable in a subroutine
"DIM grabIR(20) ' Global "
In my view this should give an error as at each subsequent entry it is already defined

Good point, I will fix it in the next release.

Geoff
Geoff Graham - http://geoffg.net
 
dasyar
Regular Member

Joined: 13/04/2015
Location: United States
Posts: 58
Posted: 02:57am 21 Dec 2015
Copy link to clipboard 
Print this post

I did get some code to convert the data from integer to string, below is a sample. When I add the 'Print convertedIR$' to the IR_int sub, it does show what I am expecting, in a string format, I hope.

The concern that I have now is, as I am adding more and more CASE statements, there seems to be something different that is occurring when I run a test IR session. For instance, I have a standard 'JohnDoe' IR code that I run, I have it set up to show the string contents all on one line, now it is starting to show up in two lines. I did not add CR to split the string after 'John'. I checked the code, and it does not have any CR added. I am not sure if this caused by the increase in CASE statements or something else is causing this.

This presents a new challenge, if I have everything put into a large buffer as the transmission occurs, and have some SUB work on the buffer to process it, it will add an unwanted affect of not having an immediate response to one word commands that I may want to send to the uMite. And then there is still the two way immediate conversation that has to be dealt with. Man is this starting to get complicated.




SUB ShowIt2
For x = 0 to y
'PRINT grabIR ' Print the array of numbers
SELECT CASE grabIR(x)
CASE 0
PRINT "1";
ccon$ = "1"
CASE 1
PRINT "2";
ccon$ = "2"
CASE 2
PRINT "3";
ccon$ = "3"
CASE 3
PRINT "4";
ccon$ = "4"
CASE 4
PRINT "5";
ccon$ = "5"
CASE 5
PRINT "6";
ccon$ = "6"
END SELECT
convertedIR$ = convertedIR$ + ccon$
Next x

END SUB
 
WhiteWizzard
Guru

Joined: 05/04/2013
Location: United Kingdom
Posts: 2944
Posted: 09:52pm 22 Dec 2015
Copy link to clipboard 
Print this post

@dasyar

I am following this thread with great interest but have been silent until now.
Two suggestions:

1> In the Sub ShowIt2; immediately above the SELECT CASE line of code (and after: For x = 0 to y) I would add the line: ccon$=""
As it stands, you will get a 'repeat' of the last ccon$ character if the value of grabIR(x) is 'invalid'. You could also use: CASE ELSE and then declare ccon$=""

2> To reduce overall code-size (and readability) as given; take out all the PRINT statements contained within each CASE and simply add one line of code after END SELECT as: PRINT ccon$;

Hope you resolve things soon . . . .

WW
 
     Page 3 of 4    
Print this page
The Back Shed's forum code is written, and hosted, in Australia.
© JAQ Software 2025