chipKIT® Development Platform

Inspired by Arduino™

Porting Lynxmotion hexapod code from Arduino to run on Uno32

Created Tue, 06 Dec 2011 17:49:56 +0000 by KurtE


KurtE

Tue, 06 Dec 2011 17:49:56 +0000

Recently I purchased an UNO32 and thought it would be fun to try to run one of robots with it, so I have started to port over my Arduino version of the Phoenix 2.1 code that I ported earlier from the Basic Atom Pro 28 code...

The first challenge was to get the PS2 remote control working. I already mentioned this on a different thread which included a version of the library code that appears to work. I now have the full program compiling and just starting to limp along.

The most recent issue, I ran into was that pgm_read_byte worked differently on the UNO than it does on normal Arduinos.

I tracked this down as our table drive ArcCos function, when the return values from the function was different for the same input... Tracked it down to these two lines:

AngleRad4 = pgm_read_byte(&GetACos[cos4/79]);
        AngleRad4 = ((long)AngleRad4*616)/c1DEC;            //616=acos resolution (pi/2/255) ;

Where when I passed in a 5909 on the Arduino the function returned 21930 but the Max32 returned -27837. Figured out that on the UNO32 it was using the byte table as a signed byte table and sign extending when it assigned the value to AngleRad4.

Fixed this one by changing to:

AngleRad4 = (byte)pgm_read_byte(&GetACos[cos4/79]);
        AngleRad4 = ((long)AngleRad4*616)/c1DEC;            //616=acos resolution (pi/2/255) ;

Now back to more debugging...

Kurt


KM6VV

Tue, 06 Dec 2011 18:35:58 +0000

With all the extra processor power, maybe run floating point, rather then a look-up table? Might not have the functions needed, 'tho.

Alan KM6VV


KurtE

Tue, 06 Dec 2011 22:48:56 +0000

Hi Alan,

Could probably do that, but would prefer to keep the code as similar as possible.

Depending on how far I wish to take this, but may try next to get the DIY XBee stuff up and running. But that implies I would need to get a working version of SoftwareSerial as I have the SSC-32 using the 2nd port and I don't like mixing the USB with other things like XBees...

Kurt


KM6VV

Tue, 06 Dec 2011 23:37:54 +0000

Hi Kurt,

I still want to do WiFi. I've got a PCB (Surveyor) for a Lantronix module coming.

Alan KM6VV


avenue33

Wed, 07 Dec 2011 17:42:08 +0000

Hi,

Join the :arrow: Question: Which WiFi Board for UNO32? thread.

The ethernet library for the Network Shield uses the Microchip Application Library TCP/IP stack and we plan to add support for the MRF24WB0MA in an upcoming version.


KM6VV

Wed, 07 Dec 2011 20:59:58 +0000

Done!

Alan KM6VV


KurtE

Thu, 08 Dec 2011 15:28:47 +0000

Hi Kurt, I still want to do WiFi. I've got a PCB (Surveyor) for a Lantronix module coming. Alan KM6VV

Sounds like fun. I noticed that there is some Lan support with the Mega32 and another shield that Digilent sells. But my first impressions was this for for wired internet...

Over the next couple of days may start playing with SoftwareSerial to make a version that is API wise compatible with the Arduino 1.0 SoftwareSerial. Not sure how far I will get. I may need another serial port (1 USB, 2 SSC-32, 3 XBee). Obviously the Max32 with 4 would be nice, but the form factor may not fit with the robots...

For software Serial, I will first simply get output to work well. Step 1, change tunedDelay to C. Probablly something like:

inline void SoftwareSerial::tunedDelay(uint16_t delay) { 
    while (delay--)
        ;
}

Then setup the table with a set of baud rates I am interested in. May only be a subset like (2400, 9600, 38400, 57600, 115200), may add in a couple others that I have used on other processors like 62500 and 125000. Then setup a simple test program that outputs a string of text and use the logic analyzer to help get the values correct. May also change code some to make the table be sparse and use the MAP function to setup any random baud rate...

Next would be to try to use the pin change interrupt on the pins that support it to try to do the background reads...

Kurt


KM6VV

Thu, 08 Dec 2011 18:15:25 +0000

Hi Kurt,

Yes, I even bought a LAN card, but haven't done anything with it yet. It could be a solution for work.

I have BlueTooth, no XBEE. I'd rather work with WiFi like the Lantronix.

Soft serial can be useful, if nothing else is available, but interrupt driven hardware is hard to beat!

"TunedDelay" is baud rate selection? A "tweek" to it?

How about using the I2C (or SPI) as the 2nd serial interface? I quickly tried that last night on a UNO, but wouldn't connect to a Wheel Commander board, probably because I tired to cheat and not use the required pull-ups. OOPS, just remembered, maybe the pull-ups weren't turned on. The SSC-32 needs an I2C version!

Alan KM6VV


KurtE

Sun, 11 Dec 2011 20:39:58 +0000

As I have mentioned, I have been playing around some with SoftwareSerial. I think I have the output working ok, for the baud rates that I care about... May add some more if I need them.

Now starting to play around with the input side. Part was to figure out how to use the Pin Change interrupt along with which pins support it. A side effect of this is I may also build a set of functions to enable the PU resistors that are also on these IO pins... This morning I had some success of at least fielding an interrupt on an IO pin :D. Not sure if anyone is interested in this stuff, but my Table that takes an Arduino (UNO32) IO pin and converts it to the Change Notify pin number CNx is:

const static uint8_t g_abMapArduinoPinToCNPin[] =  {
    0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,  0xff,   // 0-9
      13,   10,     9,     8,     4,     6,  0xff,  0xff,  0xff,  0xff,   // 10-19
       5,     7,  0xff,  0xff,  0xff,    12,  0xff,  0xff,  0xff,  0xff,   // 20-29
    0xff,  0xff,  0xff,  0xff,    14,  0xff,    15,    16,  0xff,    17,   // 30-39
      18,     3,     2,  0xff,    11};                             // 40-44

Not sure how complete or correct this is. Found some issues with the UNO32 board defs header file where the comments for pins marked as RG6 and RG7 both had the same CN number... Think I have it correct.

Again not sure if anyone else cares, but the code that I used to set up the Notify and a quick and dirty ISR that set the state of IO pin 43 (2nd led) to the state of the pin that changed is:

// Global variables to save some state info...
uint16_t 			_dat_mask; 
volatile uint32_t *		_dat_lport;
p32_regset *	ifs;		//interrupt flag register set
p32_regset *	iec;		//interrupt enable control register set
p32_regset *	ipc;		//interrupt priority...
p32_regset *    cnen;

boolean SetChangeNotifyPin( uint8_t bPin) {
  if ((bPin >= sizeof (g_abMapArduinoPinToCNPin)/sizeof(g_abMapArduinoPinToCNPin[0]))   
      || (g_abMapArduinoPinToCNPin[bPin] == 0xff)) {

    iec->clr = 0x1;  // disable the interrupts
    CNCON &= ~0x00008000; //turn "interrupt on change" off
    return false;
  }
   
  // Ok lets setup stuff for this IO pin...
  _dat_mask = digitalPinToBitMask(bPin); 
  _dat_lport = portInputRegister(digitalPinToPort(bPin));
  ifs = (p32_regset *)&IFS1;	//interrupt flag register set
  iec = (p32_regset *)&IEC1;	//interrupt enable control reg set
  ipc = (p32_regset *)&IPC6;	//interrupt priority control reg 
  cnen = (p32_regset *)&CNEN;   //enable the specific bit...

  // Now choose the appropriate bit for this pin

  cnen->reg = 1 << (g_abMapArduinoPinToCNPin[bPin]);   //enable the specific bit...
  CNCONbits.ON = 1;
  mCNSetIntPriority(2);
  mCNClearIntFlag();

  mCNIntEnable(1);

  Serial.print(ifs->reg, HEX);
  Serial.print(" ");
  Serial.print(iec->reg, HEX);
  Serial.print(" ");
  Serial.print(ipc->reg,HEX);
  Serial.print(" ");
  Serial.print(CNEN, HEX);
  Serial.print(" ");
  Serial.println(CNCON, HEX);
  
  return true;
}  

void HandleInterrupt(void)
{
  mCNClearIntFlag();
    boolean fHigh = (*_dat_lport & _dat_mask)? true : false;
    digitalWrite(43, fHigh);
//    Serial.println("Int");
}

#ifdef __cplusplus
extern "C" {
#endif
void __ISR(_CHANGE_NOTICE_VECTOR, ipl2) ChangeNoticeHandler(void)
{
    // Need to read the port to clear out the status...
  HandleInterrupt();
}
#ifdef __cplusplus
}
#endif

Still need to clean it up and remove some of the stuff that is no longer needed, now that I used the predefined macros for setting the appropriate things... And in some case move some more code over to those macros. Next step is to see what it will take to merge it into my version of Software Serial. My version will be UNO32 specific. Probably someone should generate tables like I did for the different platforms and probably integrate it into the Board_Defs.h files...

Kurt


les1943

Mon, 12 Dec 2011 21:34:47 +0000

Kurt , as a C++ novice I just about follow your code, I have been trying to get the 4D uLCD 32 to work on UNO Serial1 first results i got wrong colour, wrong string data, after hours :( I came to conclusion all the serial.print drivers fail to transmit 16 bits correctly, i have had to split the 16bit colour variable to two bytes , works fine now. Be interested to see how your version works. edit Just looked at the uLCD data sheet , I may be able to do away with the UNO altogether ! dont know how much code area is available ... more stuff to learn...

Les


KurtE

Mon, 12 Dec 2011 22:41:38 +0000

Yep, sometime soon I will start playing with my 4D system again. But keep getting myself into lots of different projects, like trying out the UNO32 (your fault).

When I ported the PS2 library to the UNO32, I ran into issues of bytes versus words. Actually 2 issues. First the system faulted as the code was casting a pointer to a byte, to be a pointer to a word and using it. The problem was the data was not then word aligned and the processor did not like it.

second issue, may have been byte order. That is on some processors, multi-byte values are ordered with the least significant byte first and others are ordered with the most significant byte first. So when you are outputting a stream with a value that is more than one byte, you are often best off, extracting the bytes in the order the device expects and output it and not assume they are in the same order.

Kurt


les1943

Tue, 13 Dec 2011 10:18:21 +0000

Kurt , Msb Lsb and word to 2xByte That sounds why the 4D colour and graphic x y positions didn't work I suspected there was also an issue with Hex 0000 . Anyway I have got display working on serial1 :D my other question relates to the other UNO serial , I need to use it for a 433Mhz transeiver I am hoping the usb / uart chip will not interfere with the output pins ? Les