![]() |
Forum Index : Microcontroller and PC projects : uMite + Parallax Hackable Badge
![]() ![]() ![]() ![]() |
|||||
Author | Message | ||||
dasyar Regular Member ![]() Joined: 13/04/2015 Location: United StatesPosts: 58 |
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 StatesPosts: 58 |
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: AustraliaPosts: 6283 |
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 StatesPosts: 58 |
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: AustraliaPosts: 1003 |
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 StatesPosts: 58 |
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: ThailandPosts: 2209 |
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 StatesPosts: 58 |
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 KingdomPosts: 4044 |
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 StatesPosts: 58 |
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 StatesPosts: 58 |
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 StatesPosts: 58 |
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: AustraliaPosts: 935 |
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 |
||||
dasyar Regular Member ![]() Joined: 13/04/2015 Location: United StatesPosts: 58 |
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 KingdomPosts: 10315 |
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 StatesPosts: 58 |
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 StatesPosts: 58 |
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: AustraliaPosts: 3292 |
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 StatesPosts: 58 |
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 KingdomPosts: 2944 |
@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 |
||||
![]() ![]() ![]() ![]() |
![]() |
![]() |
The Back Shed's forum code is written, and hosted, in Australia. | © JAQ Software 2025 |