View unanswered posts | View active topics It is currently Mon Nov 24, 2014 3:12 am






Reply to topic  [ 4 posts ] 
Help with RobotC use on HiTechnic Proto Board 
Author Message
Novice

Joined: Mon May 31, 2010 8:02 am
Posts: 55
Post Help with RobotC use on HiTechnic Proto Board
Hi,

I've just started playing around with the HiTechnic proto board and am finding the RobotC sample programs a bit hard to follow. I'm new to I2C, so that is probably part of my problem, but I thought the sample code that was provided was supposed to help out with learning about this stuff. There also appears to be basically no documentation from RobotC on how these commands are supposed to work and how the calls should be structured. Could someone provide a bit of background on this for me.

Here's the sample code provided for Experiment 1 (just a simple switch input with an LED output);

Code:
#pragma config(Sensor, S1,     PROTO_PORT,          sensorI2CCustom9V)
//*!!Code automatically generated by 'ROBOTC' configuration wizard               !!*//

/*
    Name: RBC_Exp1.c
    Author: Xander Soldaat
    Date: 28/01/2009
    Version: 0.1
    Contact: mightor_at_gmail.com

(c) Xander Soldaat & HiTechnic , 2009

*/

int inputdata;
byte outputdata;
byte cmdbuff[4];
byte respbuff[2];

/*
  42,43 - A0 input
  44,45 - A1 input
  46,47 - A2 input
  48,49 - A3 input
  4A,4B - A4 input
  4C    - B inputs
  4D    - B ouputs
  4E    - B controls
*/

// Convert an unsigned byte to an int.  RobotC doesn't currently
// support unsigned variables. This function is a work-around.
int ubyteToInt(byte _byte) {
   return (_byte & 0x80) ? (_byte & 0x7F) + 0x80 : _byte;
}

void setup() {
  cmdbuff[0] = 1;                           // Number of bytes in I2C command
  cmdbuff[1] = 0x02;                        // I2C address of protoboard

  for(int i = 0; i < 5; i++) {
    sendI2CMsg(PROTO_PORT, cmdbuff[0], 0);  // Send command to protoboard
    wait1Msec(5);
  }
}

void readdata() {
  cmdbuff[0] = 2;                           // Number of bytes in I2C command
  cmdbuff[1] = 0x02;                        // I2C address of protoboard
  cmdbuff[2] = 0x42;                        // Set read address to A0

  sendI2CMsg(PROTO_PORT, cmdbuff[0], 2);    // Send command to protoboard
  wait1Msec(10);                            // Wait for response
  readI2CReply(PROTO_PORT, respbuff[0], 2); // Read the response

  inputdata = ubyteToInt(respbuff[0]) * 4 + ubyteToInt(respbuff[1]);
}

void writedata() {

  cmdbuff[0] = 3;                           // Number of bytes in I2C command
  cmdbuff[1] = 0x02;                        // I2C address of protoboard
  cmdbuff[2] = 0x4D;                        // Set write address to B outputs
  cmdbuff[3] = outputdata;                  // The data to be written

  sendI2CMsg(PROTO_PORT, cmdbuff[0], 0);    // Send command to protoboard
  wait1Msec(5);
}

task main() {
  setup();

  cmdbuff[0] = 3;                           // Number of bytes in I2C command
  cmdbuff[1] = 0x02;                        // I2C address of protoboard
  cmdbuff[2] = 0x4E;                        // Set write address to B outputs
  cmdbuff[3] = 0x3F;                        // The data to be written
                                            // 0x3F = 111111 binary

  sendI2CMsg(PROTO_PORT, cmdbuff[0], 0);    // Send command to protoboard
  wait1Msec(5);

  while(true) {
    readdata();
    eraseDisplay();
    nxtDisplayTextLine(1, "%d", inputdata);
    if(inputdata < 512) outputdata = 0x00;
    else outputdata = 0x01;
    writedata();
    wait1Msec(50);
  }
}


A bit of clarification on the issues with Unsigned Ints would be helpful. Also, what is the setup() routine supposed to be doing and why is it sending the message 5 times? When this runs, readdata() appears to return random values until the button is pushed and then a 512 is returned. Is the returned data supposed to be random until the button is pushed? Is this because the A0 input is simply floating until the button is pressed? Why are there several wait1Msec() commands scattered around? Are these strictly required with the values specified? If anyone has any additional info, please pass it along. Appreciate the help.

Thanks,
Chris


Wed Sep 08, 2010 6:25 pm
Profile
Moderator
Moderator
User avatar

Joined: Wed Mar 05, 2008 8:14 am
Posts: 3289
Location: Rotterdam, The Netherlands
Post Re: Help with RobotC use on HiTechnic Proto Board
Hello SeaLyon,

If you are looking for a good tutorial on I2C in ROBOTC, you might be interested in this: [LINK].

The code you are looking at is something I wrote a long time ago. It was a really bare bones way of communicating with the HTPB. The setup routine is there only to make sure that the first 5 I2C transactions are ignored. I found that there was an intermittent issue between some versions of ROBOTC and the HTPB where the first 2-3 transactions would result in errors.

I can highly advise you to take a look at the driver suite I've written. It takes care of a lot of the complex stuff and has a really nice driver (and plenty of examples) for the HTPB. You can download the suite here: [LINK]. All of the examples that you've been looking at have been rewritten to make use of the driver suite and are now part of the driver suite as well. They're named "HTPB-exp1....8.c".

When you're done downloading the driver suite, be sure to check out the tutorial video and check out all of the documentation that I wrote for the suite. It will explain quite a bit. The code has a fair bit of documentation in it, too.

Below is an example of the same example you pasted but then rewritten to make use of my driver.

The waits are there to stop the screen from shearing. The LCD's hardware only allows a refresh every 100ms, so even a 50ms wait is not really long enough :)

Regards,
Xander

Code:
#pragma config(Sensor, S1,     HTPB,                sensorLowSpeed9v)
//*!!Code automatically generated by 'ROBOTC' configuration wizard               !!*//

/*
 * $Id: HTPB-exp1.c 25 2010-05-11 13:18:02Z xander $
 */

/**
 * HTPB-driver.h provides an API for the HiTechnic Protoboard.  This is program 1
 * for the HTPB experimenter's kit.
 *
 * Changelog:
 * - 0.1: Initial release
 *
 * Credits:
 * - Big thanks to HiTechnic for providing me with the hardware necessary to write and test this.
 *
 * License: You may use this code as you wish, provided you give credit where it's due.
 *
 * THIS CODE WILL ONLY WORK WITH ROBOTC VERSION 2.00 AND HIGHER.
 * Xander Soldaat (mightor_at_gmail.com)
 * 07 May 2010
 * version 0.1
 */

#include "drivers/common.h"
#include "drivers/HTPB-driver.h"

task main() {
  // Local variables
  int inputdata;

  // The data to be written: 0x3F = 111111 binary,
  // makes all digital ports outputs.
  HTPBsetupIO(HTPB, 0x3F);

  while(true) {
    // Read a 10bit wide analogue value from A0
    inputdata = HTPBreadADC(HTPB, 0, 10);
    eraseDisplay();
    nxtDisplayTextLine(1, "%d", inputdata);

    // If A0 is less than 50% of the max value
    // turn off the LED, otherwise switch it on
    if(inputdata < 512)
      HTPBwriteIO(HTPB, 0x00);
    else
      HTPBwriteIO(HTPB, 0x01);

    wait1Msec(50);
  }
}

/*
 * $Id: HTPB-exp1.c 25 2010-05-11 13:18:02Z xander $
 */

_________________
| Professional Conduit of Reasonableness
| (Title bestowed upon on the 8th day of November, 2013)
| My Blog: I'd Rather Be Building Robots
| ROBOTC 3rd Party Driver Suite: [Project Page]


Thu Sep 09, 2010 1:00 am
Profile WWW
Novice

Joined: Mon May 31, 2010 8:02 am
Posts: 55
Post Re: Help with RobotC use on HiTechnic Proto Board
Hi Xander,

Thanks for some of the clarifications. Any idea about which RobotC versions gave the errors which required the 5 dummy sends to start? Is this an issue with any RobotC versions > 2.0? I'm running 2.03 and the code appears to work fine without the setup() function. Would be nice if there were at least some comments in the code stating why setup() was there. Are you still executing the setup() function in your driver code?

Although using the driver appears to make things a bit cleaner, it comes at a HUGE memory cost. The simple program uses about 300 bytes, while the driver-based program uses closer to 4300 bytes. WOW! That's a huge price to pay for basically identical operation. I'm sure I could limit that by removing unneeded code in the includes, but who wants to do that for each project. I also lose the ability to monitor the variables in the include code, so it makes it harder to see any possible problems.

Regarding operation, you appear to change the proto board sensor definition from sensorI2CCustom9V to sensorLowSpeed9v. The LowSpeed type is not even defined in the RobotC docs. How is this different from the Custom type? What was the reason for this change in the code? The board appears to work fine using the regular sensor type. Although I haven't tried it, are there any issues running the board in CustomFast?

I know you said that the original program was outdated but it also doesn't work as written. When this program runs if displays a -1 when the button is pressed, not a value >= 512. I'm guessing this has to do with however you were attempting the conversion to unsigned int. If I change your if test to [!= -1] from [< 512], it at least works. However, at least in my setup, it displays a random value (appears to be between 0 - 3) when the button is not pressed. Any idea why it should be doing this? My connections are solid, but the read value on A0 appears to not be set at 0 when the button is not pressed (almost like its floating). Note that this occurs using either the original or the driver-based implementation.

Regarding your tutorial, did you ever do the PART 2? There are a couple of statements in the RobotC docs that seem to make sense, but I can't find any code samples on how to implement any of this;

  • Before sending an I2C “read” message, it is good practice to clear out any reply bytes that exist in the buffer.
  • You program should accommodate and recover from the occasional I2C messaging error. Lots of testing has indicated that most sensors experience errors rates of 10^-3 to 10^-5.

Was your PART 2 meant to clarify some of this? If this was never done, can you point me to any code where these recommendations are implemented so I can see what some code looks like?

Appreciate the help.

Thanks,
Chris


Thu Sep 09, 2010 4:56 am
Profile
Moderator
Moderator
User avatar

Joined: Wed Mar 05, 2008 8:14 am
Posts: 3289
Location: Rotterdam, The Netherlands
Post Re: Help with RobotC use on HiTechnic Proto Board
Chris,

SeaLyon wrote:
Thanks for some of the clarifications. Any idea about which RobotC versions gave the errors which required the 5 dummy sends to start? Is this an issue with any RobotC versions > 2.0? I'm running 2.03 and the code appears to work fine without the setup() function. Would be nice if there were at least some comments in the code stating why setup() was there. Are you still executing the setup() function in your driver code?

I am not sure if this error checking is still necessary, I have not tested this in a long time. As for the setup() in my driver code, no the error recovery is now part of the normal I2C wrapper functions. I thought it useful in case of errors with other sensors, too. It tries 5 times before giving up.

Quote:
Although using the driver appears to make things a bit cleaner, it comes at a HUGE memory cost. The simple program uses about 300 bytes, while the driver-based program uses closer to 4300 bytes. WOW! That's a huge price to pay for basically identical operation. I'm sure I could limit that by removing unneeded code in the includes, but who wants to do that for each project. I also lose the ability to monitor the variables in the include code, so it makes it harder to see any possible problems.

4300 bytes is hardly huge when you have 128KB storage. Convenience comes at a price :) You can remove the #pragma systemFile line from the includes to allow you to see the variables again. You will need to restart ROBOTC and open the files again to make it take effect. The operation is not really identical. You would need a lot of repeated code to do the same level of error checking that I've built into my wrapper functions and drivers.

Quote:
Regarding operation, you appear to change the proto board sensor definition from sensorI2CCustom9V to sensorLowSpeed9v. The LowSpeed type is not even defined in the RobotC docs. How is this different from the Custom type? What was the reason for this change in the code? The board appears to work fine using the regular sensor type. Although I haven't tried it, are there any issues running the board in CustomFast?

They are the same thing. One is pre ROBOTC 2.x and the other is post ROBOTC 2.x. HiTechnic sensors are not supported at any speeds above the 9600Hz clock speed. Don't bother using the "Faster" one, use the "Fastest", they use the same 30KHz clock speed but "Fastest" has fewer wait states.

Quote:
I know you said that the original program was outdated but it also doesn't work as written. When this program runs if displays a -1 when the button is pressed, not a value >= 512. I'm guessing this has to do with however you were attempting the conversion to unsigned int. If I change your if test to [!= -1] from [< 512], it at least works. However, at least in my setup, it displays a random value (appears to be between 0 - 3) when the button is not pressed. Any idea why it should be doing this? My connections are solid, but the read value on A0 appears to not be set at 0 when the button is not pressed (almost like its floating). Note that this occurs using either the original or the driver-based implementation.

The old programs were written for pre 2.x. I recommend people use the programs that come with the driver suite now as they are much easier to understand. Analogue inputs will always float unless tied either high or low :)

Quote:
Was your PART 2 meant to clarify some of this? If this was never done, can you point me to any code where these recommendations are implemented so I can see what some code looks like?

Check common.h, I do lots of error handling in there. Part 2 was indeed meant to clarify this. The first part was meant to be uncluttered by error checking, retries, etc.

Regards,
Xander

_________________
| Professional Conduit of Reasonableness
| (Title bestowed upon on the 8th day of November, 2013)
| My Blog: I'd Rather Be Building Robots
| ROBOTC 3rd Party Driver Suite: [Project Page]


Thu Sep 09, 2010 5:27 am
Profile WWW
Display posts from previous:  Sort by  
Reply to topic   [ 4 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.