View unanswered posts | View active topics It is currently Mon Sep 01, 2014 3:43 am






Reply to topic  [ 8 posts ] 
Strange errors 
Author Message
Rookie

Joined: Sun Aug 19, 2007 5:49 pm
Posts: 6
Post Strange errors
Hi I am new to RobotC and learning to get a long with it. As I do have a C/C++ background I am struggling with not to be able to pass arrays by reference cleanly. I have read a post that uses a typedef to pass arrays on, but nevertheless something seems odd.

If you have the time to have a look this would be great: Here is my code.
It throws an Exception in the line "msgBuf[index] = bData; " of the addArgument call.....

I am either very tired, because I do not see where my problem is, or there is something wrong here. Is there any documentation that I could have a look at? Also, opening most of the debugger windows crashed RobotC....

I am trying to get the code working for a motor multiplexer project. The multiplexer already works when I drive it through USB or I2C from another MCU, not it is time to get it working on the NXT.

Feedback would be great!


Code:
const tSensors kPort    = S1;
const short kSize     = 0;
const short kI2CAddr  = 1;
const short kLen          = 2;
const short kCmd         = 3;
const short kData         = 4;

typedef short cmdBuf[32];


void createCommmand(short nAddress, byte cmd, cmdBuf & msgBuf){
   msgBuf[kLen]  = 1;
   msgBuf[kI2CAddr] = nAddress;
   msgBuf[kCmd] = cmd;
}

void addArgument(byte bData, cmdBuf &msgBuf){
   byte nCmdLen = msgBuf[kLen];
   nCmdLen++;
   byte index = kData + nCmdLen - 2;
   msgBuf[index] = bData;
   msgBuf[kLen] = nCmdLen;
   msgBuf[kSize] = nCmdLen + 1;
}

void sendCommand(cmdBuf &cBuf, cmdBuf &rBuf){
   sendI2CMsg(   kPort, cBuf, sizeof(rBuf));
   while (nI2CStatus[kPort] == STAT_COMM_PENDING){}

   if (nI2CStatus[kPort] != NO_ERR){
         PlayImmediateTone(500,100);
   }
   else {
      readI2CReply(kPort, (byte)rBuf[0], sizeof(rBuf));
   }
}

task main()
{
   SensorType[kPort] = sensorI2CCustom;
   cmdBuf command, reply;
   createCommmand(0xa0, 0x32, command);
   addArgument((byte)'H', command);
   addArgument((byte)'a', command);
   addArgument((byte)'l', command);
   addArgument((byte)'l', command);
   addArgument((byte)'o', command);
   sendCommand(command, reply);

   return;
}


Sun Aug 19, 2007 5:59 pm
Profile
Rookie

Joined: Sun Aug 19, 2007 5:49 pm
Posts: 6
Post Still strange on 1.07
I have upgaded to 1.07. It did (seemed to) run without complaining (even though the I2C communication did not work), and then suddenly I have received the same Array Index out of Bounds exception like before.
I also had a bunch of connection problems first that I needed to fix by uploading the firmware.

Anybody an idea?

-mj


Sun Aug 19, 2007 7:02 pm
Profile
Moderator
Moderator
User avatar

Joined: Wed Jan 31, 2007 3:39 am
Posts: 299
Location: San Diego, California. USA
Post 
Hi Mj,

I downloaded the code and it compiled fine for me, Quick question did you use Add Remove programs and remove your old version before putting 1.07 in? If you didn't, it might cause strange errors to occur. Let me know, Ill keep playing with the code.

Scott B-)

_________________
Mmmm Legos B-)

My Robot Projects:
http://www.freewebs.com/robotprojects/


Sun Aug 19, 2007 7:28 pm
Profile WWW
Rookie

Joined: Sun Aug 19, 2007 5:49 pm
Posts: 6
Post 
Thnks I will try to remove the install 1.05 and then put the 1.07 in place.
Btw. can anybody explain me how exactly the I2C calls work. The documentation is a bit high level and unfortunately there is no way to have a look at the source code :).

More precisely I would like to know how the send/response buffers work. From the example code I realized that the messages need to be contained in a byte buffer with the message length as the first byte. This buffer is handed to to sendI2CMsg. I am confused about the 3rd parameter. Do I need to precisely specify how many bytes I am expecting as answer or is it the maximum length of an answer (reponse buffer size)?

The I2C protocols that I use usually on AVRs are supporting vaiable length responses. I am usually relying on the slave to signal the last byte that is being transfered. Usually the first byte received by the I2C master contains the length of the message so the master can check.

A hint on how to do check variables during debugging would also be highly appreciated. So far I have not been very lucky. Trying to use sprintf format with printDebug calls caused some kind of overloading exception.

There is definetly a need for way more documentation. What is there is better than nothing, but it stikes me that usually types are not documented.

The RobotC team should consider crowd-sourcing documentation and provide a Wiki-Page that contains a structure so that the community can fill in the gaps. Having no documentation and no sources is just frustrating.

-michael


Mon Aug 20, 2007 5:33 pm
Profile
Moderator
Moderator
User avatar

Joined: Wed Jan 31, 2007 3:39 am
Posts: 299
Location: San Diego, California. USA
Post 
Im still a little Iffy on my I2c communications as well, I just learned some new tricks that might help you out.

First thing is to make sure that you have Robot C 1.07 installed and under the Window tab / menu level, make sure Expert is checked.

there is a Test I2c utility located under the Robot tab/ Nxt Brick. It looks like you can play with I2c messages and get replys back without writing any code. I just read about it today so i haven't played with it, but it looks powerful to test messaging out.

Now that expert mode is selected, there should now be a long list of commands located in the Code Templates menu on the left of the screen. If you double click on Sensors Digital it has these I2c commands briefly described

sendI2CMsg(nPort, sendMsg, nReplySize);
readI2CReply(nPort, replyBytes, nBytesToRead);

it appears that when sending a message, you have to specify the number of bytes your exspecting back from the I2c device, if you put 0 the device will not reply.

The best way iv found to check variables while running a program is to use the nxt display to print it on the screen. I use this command usually:
nxtDisplayTextLine(nLineNumber, sFormatString, parm1, parm2);
This will let you print it on the screen and monitor it easily
nxtDisplayTextLine(0, "TextA: %d", VariableA);
nxtDisplayTextLine(1, "TextB: %d", VariableB);
nxtDisplayTextLine(2, "TextC: %d %d", VariableA, VariableB);

There is a Robot C Wiki page located at http://www.robotc.net/wiki/index.php?title=Main_Page
It looks like nobody's added anything yet.

Hope this all help you out
Scott B-)

_________________
Mmmm Legos B-)

My Robot Projects:
http://www.freewebs.com/robotprojects/


Mon Aug 20, 2007 11:02 pm
Profile WWW
Rookie

Joined: Sun Aug 19, 2007 5:49 pm
Posts: 6
Post 
Hi Scott,
seems you are around for quite a while and if even you don't know precisely how the stuff works then something is severely wrong. The Wiki does not have enough structure and content to be helpful. The knowledgable guys (creators) have to provide a critical mass of information that encourage people to jump on it. A Wiki that just does not contain anything will not inpire anybody.

So far I am only working on RobotC cause a friend wants to use with my sensors and motor multiplexers. The NXT brick is a need standarized piece that fits well with the AVR based pieces that I worked on. I am not so sure currently that I will stick to RobotC one I have the stuff working.

-mj


Tue Aug 21, 2007 4:10 am
Profile
Rookie

Joined: Sun Aug 19, 2007 5:49 pm
Posts: 6
Post 
I am still curios if the answer given by the I2C device MUST be nReplySize bytes long or if this is just the max size of the reveive buffer.
But reading through the documentation there is a ring buffer that will contain the replied bytes. The doc also sais that it is good practice to clean this buffer, but it does not say how (what is the buffer size?!?). The whole paradigm of these calls is a bit odd, cause they already represent an abstraction on-top of I2C. Looks like the sendI2CMsg call actually initiates 2 transfers if nReplySize > 0. At the same time you can read that I2C communication tends to be slow and should be encapsulated in a task. So why not implement the most basic functionality and rely on the programmer to provide the higher level abstraction?

Also does anybody know the possible states that can be contained I2CStatus array?! And what they mean?

The I2C "debug tool" looks useful if only I knew how to pass non printable characters (does somethingn like '\x14' work?!?)

-mj


Tue Aug 21, 2007 11:52 am
Profile
Rookie

Joined: Sun Aug 19, 2007 5:49 pm
Posts: 6
Post 
Ok. Found the main issue:
typedef short cmdBuf

Ok. Found the main issue:

typedef short cmdBuf[];

should be byte and not short :) and nothing worked because I2C was calling on the wrong address....


Now I am going to do some research :)

-mj


Tue Aug 21, 2007 4:28 pm
Profile
Display posts from previous:  Sort by  
Reply to topic   [ 8 posts ] 

Who is online

Users browsing this forum: No registered users and 2 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  



Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by ST Software for PTF.