SIRC C code and cog_run()
Rsadeika
Posts: 3,837
in Propeller 1
Not sure what is going on, but the SIRC function starts to act weird, after I start using the remote, when SIRC is run in its own COG.
I have inserted fresh batteries in the early edition of the Parallax remote controller. I am also using the Parallax IR demodulator. The IR circuit is wired just like the example in the Learn site. When I first start the program and start using the remote control, all is working as expected. But it does not take to long before the remote control is having no effect, basically I am pressing the necessary button and it is not working. It seems to take effect after I have pressed the button a whole bunch of times. At one point I did add a pause(150) in the SIRC while loop, that made it even worse.
Now I did try using the same setup, but had it in the main function (SIRC control is not in a COG), and it seem to work as expected, even after an extended period of time of pressing the necessary buttons. I am using the original Activity Board, and I have it set in CMM mode.
I also ran a test with my QuickStart+HIB setup, it worked there as expected, both in COG and regular function. It seems that the remote is not suffering from sticky keys, since it works fine in non COG mode.
Did something change with the new cog_run() function? I am using the latest Windows 7 SimpleIDE version. If I get a chance I will have to try this out with Linux SimpleIDE, but I think that version does not have a SIRC library, IIRC.
The program is fairly long, when I looked through it, I did not find any blatant errors.
Ray
I have inserted fresh batteries in the early edition of the Parallax remote controller. I am also using the Parallax IR demodulator. The IR circuit is wired just like the example in the Learn site. When I first start the program and start using the remote control, all is working as expected. But it does not take to long before the remote control is having no effect, basically I am pressing the necessary button and it is not working. It seems to take effect after I have pressed the button a whole bunch of times. At one point I did add a pause(150) in the SIRC while loop, that made it even worse.
Now I did try using the same setup, but had it in the main function (SIRC control is not in a COG), and it seem to work as expected, even after an extended period of time of pressing the necessary buttons. I am using the original Activity Board, and I have it set in CMM mode.
I also ran a test with my QuickStart+HIB setup, it worked there as expected, both in COG and regular function. It seems that the remote is not suffering from sticky keys, since it works fine in non COG mode.
Did something change with the new cog_run() function? I am using the latest Windows 7 SimpleIDE version. If I get a chance I will have to try this out with Linux SimpleIDE, but I think that version does not have a SIRC library, IIRC.
The program is fairly long, when I looked through it, I did not find any blatant errors.
Ray
/* cr_ab.c This is the iRobot Create Control System using the Parallax Activity Board November 28, 2016 */ #include "simpletools.h" #include "simpletext.h" #include "fdserial.h" #include "sirc.h" serial *xbee; serial *create; int highbyte,lowbyte; float newbyte; /* COGed Functions */ void irrem(); /*******************/ void menu(); /* Create control commands. */ int speed_right = 75; int speed_left = 75; int turn_left = 35; int turn_right = 35; int highbyte,lowbyte; float newbyte; void CRstop(); void CRfore(); void CRback(); void CRleft(); void CRrite(); void CRsafe(); void CRstart(); void BattChrg(); /*******************/ int main() { // Add startup code here. /* Rx Tx BAUD */ xbee = fdserial_open(11, 10, 0, 9600); pause(250); create = fdserial_open(12, 13, 0, 57600); pause(250); //fdserial_txChar(create,128); //pause(400); //fdserial_txChar(create,131); //pause(500); cog_run(irrem,128); /* XBee intro message. */ writeStr(xbee,"iRobot Create Robot Control System.\n"); menu(); char inBuff[40]; while(1) { // Add main loop code here. writeStr(xbee,">"); readStr(xbee,inBuff,40); if(!strcmp(inBuff, "help")) menu(); else if(!strcmp(inBuff, "crstop")) CRstop(); else if(!strcmp(inBuff, "crfore")) CRfore(); else if(!strcmp(inBuff, "crback")) CRback(); else if(!strcmp(inBuff, "crrite")) CRrite(); else if(!strcmp(inBuff, "crleft")) CRleft(); else if(!strcmp(inBuff, "crsafe")) CRsafe(); else if(!strcmp(inBuff, "crstart")) CRstart(); else if(!strcmp(inBuff, "crcharge")) { BattChrg(); writeFloat(xbee,newbyte/1000); writeStr(xbee," Create Volts\n"); } else { writeLine(xbee,"Invalid Command"); } } } /* COGed functions */ void irrem() { while(1) { if(sirc_button(14) == 21) CRstop(); else if(sirc_button(14) == 29) CRsafe(); else if(sirc_button(14) == 25) CRstart(); else if(sirc_button(14) == 16) CRfore(); else if(sirc_button(14) == 17) CRback(); else if(sirc_button(14) == 18) CRrite(); else if(sirc_button(14) == 19) CRleft(); } } /*********************************************/ /* Create commands */ void CRstop() { fdserial_txChar(create,145); fdserial_txChar(create,0); fdserial_txChar(create,0); fdserial_txChar(create,0); fdserial_txChar(create,0); } void CRfore() { fdserial_txChar(create,145); fdserial_txChar(create,((speed_right)>>8)&0xFF); fdserial_txChar(create,((speed_right)&0xFF)); fdserial_txChar(create,((speed_left)>>8)&0xFF); fdserial_txChar(create,((speed_left)&0xFF)); } void CRback() { fdserial_txChar(create,145); fdserial_txChar(create,((-speed_right)>>8)&0xFF); fdserial_txChar(create,((-speed_right)&0xFF)); fdserial_txChar(create,((-speed_left)>>8)&0xFF); fdserial_txChar(create,((-speed_left)&0xFF)); } void CRleft() { fdserial_txChar(create,145); fdserial_txChar(create,((turn_right)>>8)&0xFF); fdserial_txChar(create,((turn_right)&0xFF)); fdserial_txChar(create,((-turn_left)>>8)&0xFF); fdserial_txChar(create,((-turn_left)&0xFF)); } void CRrite() { fdserial_txChar(create,145); fdserial_txChar(create,((-turn_right)>>8)&0xFF); fdserial_txChar(create,((-turn_right)&0xFF)); fdserial_txChar(create,((turn_left)>>8)&0xFF); fdserial_txChar(create,((turn_left)&0xFF)); } void CRsafe() { fdserial_txChar(create,128); pause(400); fdserial_txChar(create,131); } void CRstart() { fdserial_txChar(create,128); } void BattChrg() { fdserial_txChar(create,142); fdserial_txChar(create,22); highbyte = fdserial_rxChar(create); pause(50); lowbyte = fdserial_rxChar(create); newbyte = ((highbyte << 8) + lowbyte); } /*********************************************/ void menu() { writeStr(xbee,"Menu - help, \n"); writeStr(xbee,"crcharge, crstop, crfore, crback, crleft, crrite \n"); writeStr(xbee,"crsafe, crstart, \n"); }
Comments
When the COG started up, on the remote terminal, all It was doing was the curser was jumping all over the screen. I got the impression that maybe the readStr() command was not working the way it is supposed too, in the while loop. I am starting to wonder if even, in CMM mode, starting a new COG is being treated like a pthread within SimpleIDE (PropGCC), if that makes any sense.
Not sure as to why I am starting to run into all these problems using SimpleIDE. Previously, a few years back, I do not recall having this many problems.
Ray
- Variables that are used in multiple threads / cogs will very probably need to be marked as volatile. The optimizer in GCC will do things like load a variable from hub ram into a cog register and repeatedly use it from there because it's faster. If you have two different cogs / threads interacting with a variable, marking the variable as volatile makes sure that each time the variable is used, it is loaded from / written to memory so that other threads using it will see the most recent changes.
- launching a cog in C/C++ has different stack space requirements than launching one in Spin. I believe the minimum stack size is 40 longs just for interpreter working space (you should double check this, as it's from memory). I typically use 64 longs as my stack.
- I haven't used cog_run() myself, but use cogstart, like this: cogstart( &EntryFunction, Param, stackAddress, stackSizeInBytes );
At the moment I am just using one or the other, mostly the IR remote for testing. But eventually I will probably be using both, XBee and IR.
The new cog_run() command requires a stack space amount, I have been using 128, and also had it up too 256, made no difference in functionality.
I just did a test using the switch loop instead of the 'if' 'else if' loop, made no difference, the SIRC COG starting acting up.
Ray
The one thing that I just noticed, was that the Create has a docking station, which I think sends out some of its own IR signals, not sure if this is having an effect on the IR demodulator that I am using. Since the robot just went red (need a charge), after it charges, I will have to try blocking the IR mechanism on the docking station, and see if this makes a difference.
Ray
So, the robot got charged up, I blocked the IR on the docking station, and the program seems to be working as expected. This creates a new problem, how do I block out the signals from the docking station or have my program and IR demodulator disregard the signals from the docking station? I was hoping to be able to use the Create IR and the docking station IR for a custom docking program.
Well at least I found the SIRC problem, I hope.
Ray