TEN-TEC Introduces an open-source QRP transceiver powered by chipKIT Uno32

Rebel

TEN-TEC launched a new QRP transceiver based upon a completely different platform than any other rigs they have in production: a QRP radio, built on the chipKIT Uno32™ (Arduino-based software) to be known as the Model 506 Rebel.

The TEN-TEC Rebel model 506 transceiver is designed with the purpose of providing Ham Radio operators a platform for developing and writing code using the open-source Arduino programming environment. It is a factory built CW QRP radio with a Chip Kit Uno 32 Arduino compatible processing unit that holds the operating program. The radio is provided with programming for basic operating functions that allow it to be used immediately as a basic QRP transceiver. Additional operating functions can be programmed by the user, either by writing the code or copying/adapting code developed by members of a growing  number of Arduino special interest groups. It is this sharing of programming routines and ideas for functionality that is the heart of the Arduino open-source concept.

Basic features include a 40 & 20 meter QRP transceiver with internal jumpers to change bands.  Full band coverage on both bands.  Typical power output will run 4-5 watts with 13.5 VDC.  A drift free operation is achieved through DDS synthesizer technology.  CW sidetone through headphones. Three filter bandwidth choices and three tuning rate adjustments included with the stock program.

You can check the details at the product webpage 

Tom Witherspoon, a hobbyist, wrote a review for the Rebel at his website QRPer

VN:F [1.9.22_1171]
Rating: 0.0/10 (0 votes cast)
VN:F [1.9.22_1171]
Rating: 0 (from 0 votes)

MultiWII lib on ChipKit

Hello, The MultiWII lib is used to control various multi copters using RC, IMU, motors, servos… It is currently running on Arduino platform and I have started to migrate it on ChipKit. The main difficulty porting this lib is that it is very hardware dependent using special Arduino registers and mechanisms (for example eeprom) that are different on PIC. I have made a first build  Lib MuliWii on ChipKit release Alpha and I will start testing soon. I will keep you posted…    
VN:F [1.9.22_1171]
Rating: 0.0/10 (0 votes cast)
VN:F [1.9.22_1171]
Rating: 0 (from 0 votes)

Robot camera based on chipKIT Max32 and controlled by Wifi/Xbee or stand-alone


Max32

chipKIT Max32-based robot
chipKIT Max32-based robot

The chipKIT Max32™ is based on the popular Arduino™ open-source hardware prototyping platform but adds the performance of the Microchip PIC32 microcontroller. The Max32 is the same form factor as the Arduino™ Uno board and is compatible with many Arduino™ shields. It features a USB serial port interface for connection to the IDE and can be powered via USB or an external power supply.

The Max32 board takes advantage of the powerful PIC32MX795F512 microcontroller. This microcontroller features a 32-bit MIPS processor core running at 80 MHz, 512K of flash program memory and 128K of SRAM data memory. In addition, the processor provides a USB 2 OTG controller, 10/100 Ethernet MAC and dual CAN controllers that can be accessed via add-on I/O shields.

The Max32 can be programmed using an environment based on the original Arduino™ IDE modified to support PIC32. In addition, the Uno32 is fully compatible with the advanced Microchip MPLAB® IDE and the PICKit3 in-system programmer/debugger.

Note that initially I have used the chipKIT Uno32™ but I have reached the limit of the  flash program memory (128K) when I have added the TCP and WIFI libs, so I have migrated to the chipKIT Max32™ that allows 512K of flash program memory.

Four-wheel-drive

I use the Baron four-wheel-drive robot from DFRobot with 2 encoder sensors in order to retrieve the speed of the two front motors right and left. This is useful to control the direction and to implement a PID processus. The assembly of the encoders is described in the doc installation-method-fit0029.pdf. You can also get the complete installation doc here.

Warning, there is a design flaw in the mounting encoders because they rub. Therefore, it is necessary to add a nut on the screw that secures the encoder so that the disc does not rub it in his rotation.

The specs are:

  • Complete Machine Weight: 614g
  • Wheel Diameter : 65mm
  • Highest Speed: 61cm/s

Engine Feature:

  • Gear Ratio : 1:120
  • No-load speed (3V): 100RPM
  • No-load speed (6V): 200RPM
  • No-load current (3V): 60mA
  • No-load current (6V): 71mA
  • Stall current (3V): 260mA
  • Stall current (6V): 470mA
  • Torgue (3V): 1.2Kgcm
  • Torque (6V): 1.92Kgcm
  • Weight : 45g

Power

I use a block of 5 AA batteries 1.5 V for a total of 7.5 V to power the chipKIT Max32 via the external power connector.

The chipKIT Max32 provides an regulated output voltage of 3V and 5V used to supply the other components: servos, IR sensor, compass … with the exception of the engines that are powered by one battery Lipo 2S 7.4V 350mAh

Motor interferences

The engines used are not brushless, that is to say they are made of brush that transmit power to the rotor (rotating part of the motor) and rub on an armature. This friction produces sparks that cause parasitic currents.

To remove these currents, I added a 100 nF capacitor non-polarized (ceramic) between the two motor terminals to intercept these parasitic currents. You can also add two other smaller capacitors (10 nF) between each terminal and the metal casing.

In all cases, the capacitors should be soldered close to the terminals for reasons of efficiency.

H-Bridge

A microcontroller is unable to provide the necessary current to a motor, why is it always a power stage before engines.

The speed of an electric motor is not proportional to the voltage at its terminals. The motor requires a minimum voltage large enough to start. If it is too low, the electromagnetic forces are not sufficient to combat friction. This makes it difficult to adjust the speed accurately.

The solution to this problem is clever. Simply provide the motor with a voltage that is always the same is the maximum voltage! But this voltage will be applied only in very short periods of time. By adjusting the length of these periods of time, you get to move faster or slower engines. More, we note that the motor speed is proportional to the length of periods of time. Controlling the length of time spent at the maximum voltage with respect to time without voltage application (zero voltage) is the heart of the solution. In fact, this solution is very well known in control systems and electronics and is known as PWM (Pulse Width Modulation).

A PWM signal is not generated by an H-bridge. But the fact that H-bridge is made up of transistors makes it particularly suitable to be controlled by a PWM signal. We must see the couple PWM and H-bridge as a particularly effective tool to control electric motors.

There are several models of H-bridges, I have chosen the L298 because it allows up to 4A and also because DF Robot proposes a module ready using this circuit, named 2A Dual Motor Controller. I have first used the L293D which is also a good choice but limited to 1A. As I had many problems with my soldiers, I preferred an already installed system.

One L298 is used to control 2 motors, so I use 2 L298 to control the robot. They are powered by one battery Lipo 2S 7.4V 350mAh for both parts logic and driven of the voltage.

The way to control the motor is the following:

  • Enable bit allows the engine power. As previously explained it received a PWM signal.
  • The pins IN1 and IN2 of the L298 are used to manage the direction of the motor. The 2A Dual Motor Controller includes several NAND gates in order to combine IN1 and IN2. So at the end, only one pin is needed to control the direction.

The connectivity between the two 2A Dual Motor Controller and the chipKIT is the following.

Pins IN are connected to the standard digital pins of chipKIT while Enable pins are connected to the PWM pins of chipKIT in order to use the functions analogWrite () that rely on timers Oci:

#define InMotorRight1Pin  30      // In pin of Motor controller #1 for motor right #1 connected to digital pin J9-08(PMD7/RE7)
#define EnableMotorRight1Pin 3    // Enable pin of Motor controller #1 for motor right #1 connected to PWM pin J14-07(SDO1/OC1/INT0/RD0)   Use TIMER_OC1
#define InMotorRight2Pin  31      // In pin of Motor controller #1 for motor right #2 connected to digital pin J9-07(PMD6/RE6)
#define EnableMotorRight2Pin 5    // Enable pin of Motor controller #1 for motor right #2 connected to PWM pin J14-11(OC2/RD1)   Use TIMER_OC2
#define InMotorLeft1Pin  32       // In pin of Motor controller #2 for motor left #1 connected to digital pin J9-06(PMD5/RE5)
#define EnableMotorLeft1Pin 6     // Enable pin of Motor controller #2 for motor left #1 connected to PWM pin J14-13(OC3/RD2)    Use TIMER_OC3
#define InMotorLeft2Pin  33       // In pin of Motor controller #2 for motor left #2 connected to digital pin J9-05(PMD4/RE4)
#define EnableMotorLeft2Pin 9     // Enable pin of Motor controller #2 for motor left #2 connected to PWM pin J3-03(OC4/RD3)    Use TIMER_OC4

Encoders

2 encoder sensors mounted on Both left and right forehead engine can calculate the motor speed and check for proper rotation at the same speed so that the robot has a straight path. In case of discrepancy, a small PID (feedback control method based on Proportional Integral Derivative errors) algorithm is used to compensate the gap by accelerating the slowest engine or braking the fastest. To date, the results of encoders seem imprecise, therefore I disconnected the call to the PID routine.

They are connected to the interrupt pins INT3 and INT4 of chipKIT in order to get at any time the number of ticks achieved by each engine. One encoder generates 20 voltage changes per round that trigger consequently 20 interruptions per round. I use the pins INT3 and INT4 to catch the interruptions in order to don’t busy the cpu. Be careful to define the pins as input before calling the attachInterrupt function that configures the interruptions.

The connectivity between the 2 encoders and the chipKIT is the following:

#define EncoderTickRightINT  4   // INT used by the encoder for motor right connected to interrupt pin INT4 J4-02(AETXEN/SDA1/INT4/RA15)  Use INT4
#define EncoderTickLeftINT   3   // INT used by the encoder for motor left connected to interrupt pin INT3 J4-01(AETXCLK/SCL1/INT3/RA14) Use INT3

IR Sensor

IR Sensor GP2Y0A21YK can detect obstacles. It is connected to one of the analog pins of chipKIT in order to use the function analogRead() that converts a voltage to a value between 0 and 255 using the ADC module of the PIC.

This number is converted to cm follows based on the chart provided to a voltage of 3V in the GP2Y0A21YK datasheet.

The measured distances are in the range 15 cm – 70 cm, therefore we must regularly measure failing to detect an obstacle too late. Note that you can also use 5V but you lose precision.

It is connected to a standard analog pin of chipKIT.

The connectivity between the IR Sensor and the chipKIT is the following:

/* Analog interface is provided on pin V0
   Power +3V is set on pin VCC          
   Ground is set on pin GND                 
*/
#define GP2Y0A21YK_Pin 54   // IR sensor GP2Y0A21YK analog pin J5-01 A0 (PGED1/AN0/CN2/RB0)   Use ADC module channel 2

IR Servo

The infrared sensor GP2Y0A21YK is mounted on a Servo in order to identify barriers in different directions, especially front, right and left. The servo is controlled by pulses of 20 ms period and a width between 1 and 2 ms. These pulses are managed by the software PWM lib which allows to manage multiple servos with only one timer of the PIC and to connect to a standard digital pin.

The connectivity between the IR Servo and the chipKIT is the following:

/* Power +5V
   Ground    
*/
#define IRSERVO_Pin 36   // IR Servo pin connected to digital pin J9-02 (PMD1/RE1)

Compass

A compass CMPS03 is connected to provide the direction. This compass communicates with the PIC via the I2C interface using standard wire library. We can know the direction by asking via the I2C protocol the values of the register of the Compass.

The I2C address is defined as follows:

#define CMPS03_ADDRESS 0x60 //1100000: compass address 0XC0 on 7 bits for I2c protocol

After several tests, I placed the compass away from the metal base of the robot motors and servos because it provided results completely wrong. Also, be careful to put it horizontally for better accuracy.

The chipKIT Max32 handles 5 max I2c interfaces but the standard wire library manages only 1. By default, this lib uses the I2C1 but I can’t use this interface because the corresponding pins are shared with INT3 and INT4 that are required by the encoders. So I have updated the core file Board_Defs.h in order to use I2C2 interface instead of I2C1.

#define _TWI_BASE       _I2C2_BASE_ADDRESS

#define _TWI_BUS_IRQ    _I2C2_BUS_IRQ

#define _TWI_SLV_IRQ    _I2C2_SLAVE_IRQ

#define _TWI_MST_IRQ    _I2C2_MASTER_IRQ

#define _TWI_VECTOR     _I2C_2_VECTOR

#define _TWI_IPL_ISR    _I2C2_IPL_ISR

#define _TWI_IPL        _I2C2_IPL_IPC

#define _TWI_SPL        _I2C2_SPL_IPC

Moreover, I have connected these pins to +5 V via a pull-up resistor of 1K necessary to manage the I2C bus protocol.

The connectivity between the Compass and the chipKIT is the following:

/* Compass                                                              
        I2C interface is provided on pins:                                   
        1 = Power +5V                                               
        2 = SCL connected to J3-09 (SCL2/RA2)                        
        3 = SDA connected to J3-11 (SDA2/RA3)                        
        9 = Ground                              
*/

Temperature

A temperature sensor TMP102 is connected to provide the temperature. This temperature sensor communicates with the PIC via the I2C interface using standard wire library. We can know the temperature by asking via the I2C protocol the values of the register of the sensor.

The I2C address is defined as follows:

#define TMP102_ADDRESS 0x48 //1001000: temperature sensor address 0X90 on 7 bits for I2c protocol

Refer to the previous Compass section for the details regarding the I2C connection. Camera

A camera is connected to make pictures. This camera communicates with the PIC via the UART2 interface at 38400 bauds using standard Serial library. I have dedicated UART2 to this component in order to avoid any conflict with other Serial interfaces (log, XBee…).

The camera requires a specific initialization procedure:

  1. Flush out any data currently in the serial buffer
  2. Send RESET_CAMERA command
  3. Wait for the camera answer that contain several data like revision number and terminates by “Init end\x0d\x0a”
  4. Wait 3 seconds

The way to make a picture is the following:

  • Send TAKE_PICTURE command in order to ask the camera to make the picture and store it in its own memory
  • Send GET_SIZE command in order to get the size of the image currently stored in the camera
  • Send GET_DATA command in order to read the data from the camera. They are read in chunks of 32 bytes and then stores in a file on a SD Card. End of file is detected at reception of the bytes 0xFF and 0xD9 (standard JPEG file eof)
  • Once the image is stored on the SD Card, it can be transmit later to any client via the XBee or Wi-Fi interface. It should be possible to not use a SD-Card and publish directly the image in real-time to a XBee or a WIFI interface but this will be more complex, especially regarding the synchronization between the communication with the camera on one side and with the Xbee/Wifi on the other side.
  • In addition, this camera is mounted on a Tilt&Pan driven by 2 servos in order to allow horizontal and vertical moves.

The connectivity between the Camera and the chipKIT is the following:

/* Camera                                                                
        UART2 interface is provided on pins:                                  
        1 = Power +5V                                                  
        2 = TX connected to J4-04 (AETXD1/SCK1A/U1BTX/U1ARTS/CN21/RD15)
        3 = RX connected to J4-03 (AETXD0/SS1A/U1BRX/U1ACTS/CN20/RD14)
        4 = Ground                                                     
*/

Tilt&Pan Servos

The camera is mounted on a Tilt&Pan driven by 2 servos in order to allow horizontal and vertical moves. These servos are managed like the IR servo.

The connectivity between the Tilt&Pan Servos and the chipKIT is the following:

/* Power +5V
   Ground    
*/
#define HSERVO_Pin  34   // Horizontal Servo pin connected to digital pin J9-04 (PMD3/RE3)

/* Power +5V
   Ground    
*/
#define VSERVO_Pin  35   // Vertical Servo pin connected to digital pin J9-03 (PMD2/RE2)

SD Card

SD card is used to store the images taken by the camera. The SD Card communicates with the PIC via the SPI interface.

WARNING: There is a conflict using SD-Card and WIFI as described by KeithV from Diligent. The problem is the Wi-Fi and SD both share the same SPI port and the Wi-Fi module responds to INT1 on the WiFiShield. If you are reading the SD card when the Wi-Fi gets an interrupt, the PIC will CS the Wi-Fi module and both the SD and Wi-Fi SPI devices will be selected and corruption occurs. Following the proposal of KeithV, I have updated the standard SD Card lib in order to disable INT1 while reading/writing the SD card.

Communication

The robot can communicate using XBee or WIFI. I have written a small Java interface in order to communicate with the robot allowing both protocols but only one mode is available at one time because it depends on the shield plugged to the main chipKIT Board.

XBee Communication / WIFI Communication

I use the chipKIT Wi-Fi Shield™ which is based on the Microchip MRF24WB0MA Wi-Fi module. It communicates with the PIC via SPI and it uses also INT1 (warning refer Conflict in SD Card section). It is intended for use with the Digilent network libraries, DNETcK and DWIFIcK. Be careful because these lib are huge (60K), it is the reason why I have migrate from Uno to Max.

I have used these libs to build a mini HTTP server that listens to one port and establishes a connection if a client tries to connect. Then the message received is parsed in order to determine which command is required and the optional parameters. I have defined the following format for the message:

CMD=command&PARAM=param1;param2;

where command is the command required and param1, param 2.. are the optional parameters with” ;” as separator. CMD and PARAM are the two keywords.

Once the command is processed by the robot, it answers with the following format (Content-Type: text/html):

Field 0:value0; Field 1:value1;

where value0, value1 are the optional answers with” ;” as separator. Field is keyword.

In case of command that triggers a picture, the answer is composed of the stream of bytes (Content-Type: application/octet-stream) that represent the content of the JPEG file.

On this picture, you can see the 3 levels:

IMG_4910
  • Lower level: Wheels, motors, battery box to power the chipKIT
  • Intermediate level: H-bridges, lipo battery motors, IR sensor mounted on the servo
  • Higher level: chipKIT shield + Wifi / SD card, board integrated compass and temperature sensor, photo sensor mounted on Pan & Tilt

Motors control

I have written a lib that manage the speed of the 4 motors using the encoders, the direction using the Compass and detects the obstacles using the IR sensor mounted on a servo.

The functions of the lib are the following:

void IntrTickRight(); //interrupt handler encoder right
void IntrTickLeft(); //interrupt handler encoder right

int motor_begin(); //initialize everything, must be called during setup 

int get_TickRight(); //get Tick Right
int get_TickLeft(); //get Tick Left
void reset_TickRight(); //Description: reset TickRight
void reset_TickLeft(); //Description: reset TickLeft
int get_SpeedMotorRight(); //get Speed Motor Right
int get_SpeedMotorLeft(); //get Speed Motor Left 

void forward(int motor);  //Description: set IN1 and IN2 of the corresponding motors in order to run clockwise 
void forward_test(int num);  //set IN of the motor num in order to run clockwise 
void start_forward(); //call forward +  set enable pin of the 4 motors to SPEEDNOMINAL 
void start_forward_test(int num); //call forward +  set enable pin of the motor num to SPEEDNOMINAL 
void backward(int motor); //Description: set IN1 and IN2 of the corresponding motor in order to run anti-clockwise 
void start_backward(); //call backward +set enable pin of the 4 motors to SPEEDNOMINAL 
void stop(); //set IN of the 4 motors in order to stop 

int accelerate (int motor); //set enable pin of the corresponding motors to an higher value (1 increment) 
int accelerate_n (int motor, int n);  //set enable pin of the corresponding motors to an higher value (n increments) 
int deccelerate(int motor); //set enable pin of the corresponding motors to a lower value (1 decrement) 
int deccelerate_n(int motor, int n); //set enable pin of the corresponding motors to a lower value (n decrements) 

int adjustMotor (int motor, int pid); //Adjust the speed of the motor according the PID value
int go(unsigned long timeout, int pid_ind); //go during timeout seconds or before in case of obstacle detected by IR sensor. If pid_ind = 1 then use a PID method (calling adjustMotor) to control motors speed between left and right

int check_around();  //move the servo used by the IR sensor in order to determine  the direction without obstacle 

int turn(double alpha, unsigned long timeout); //turns with an angle of alpha degrees before a delay (timeout) using a compass to get the direction
int turnback(unsigned long timeout); //turns back before a delay (timeout)

Robot control

I developed a Java application with Eclipse, it can send commands to the robot and display information from the robot. As described earlier, it can use WiFi or XBee communication.

The available commands are:

START: Start the robot forward at cruise speed, cancels any previous GO command.
STOP: Stops the robot, cancels any previous GO command.
INFO: Retrieves information of the robot status Start / Stop, theoretical speed, actual speed, temperature, distance barrier, direction.
PICTURE: Ask the robot to take a picture, to store it on the SD card and to return it by WIFI or XBee, the robot is stopped for the photo.
TURN_RIGHTTurn_right + angle: Ask the robot to turn right at an angle. If this angle = 180, then the robot changes direction.
TURN_LEFT+ angle: Ask the robot to turn left at an angle. If this angle = 180, then the robot changes direction.
CHECK_AROUND: Ask the robot to determine the direction without obstacle (front, left or right)
MOVE_TILT_PAN + angle1 + angle2: Ask the robot to move the Pan & Tilt of the camera according to the angles of horizontal and vertical deflection.
GO + time: Start the robot forward at cruise speed,then left it autonomous for a while.
Sources

All the sources are in Git:

Core resources

In order to avoid any conflicts between the components of the Robot, it is important to know in detail which core resource are used by each component.

Here is the summary including some details about the use of the core resources:

/*
Enable 4 motors (analogwrite)
**********************************
use TMR2 and TIMER_OC1,TIMER_OC2, TIMER_OC3, TIMER_OC4, TIMER_OC5 to generate PWM
*/
       // If no PWM are currently active, then init Timer2
        if (pwm_active == 0)
        {
                    T2CON = T2_PS_1_256;
                    TMR2 = 0;
                    PR2 = PWM_TIMER_PERIOD;
                    T2CONSET = T2_ON;
        }
		
        //generate bit mask for this output compare
        //should assert(timer < 8) here, but assertions aren't being used
        pwm_mask = (1 << (timer - _TIMER_OC1));

        //Obtain a pointer to the output compare being being used
        //NOTE: as of 11/15/2011 All existing PIC32 devices
        // (PIC32MX1XX/2XX/3XX/4XX/5XX/6XX/7XX) have the output compares
        // at the same addresses. The base address is _OCMP1_BASE_ADDRESS
        // and the distance between their addresses is 0x200.
        ocp = (p32_oc *)(_OCMP1_BASE_ADDRESS + (0x200 * (timer - _TIMER_OC1)));

        // If the requested PWM isn't active, init its output compare
        if ((pwm_active & pwm_mask) == 0)
        {
                    ocp->ocxR.reg   = ((PWM_TIMER_PERIOD*val)/256);
                    ocp->ocxCon.reg = OC_TIMER2_SRC | OC_PWM_FAULT_PIN_DISABLE;
                    ocp->ocxCon.set = OC_ON;
                    pwm_active |= pwm_mask;
        }

        // Set the duty cycle register for the requested output compare
        ocp->ocxRs.reg = ((PWM_TIMER_PERIOD*val)/256);

/*
Encoders 2 motors
**********************
use interrupts INT3 and INT4
*/
        IEC0bits.INT3IE         =       0;
        IFS0bits.INT3IF         =       0;
        INTCONbits.INT3EP       =       edge;
        IPC3bits.INT3IP         =       _INT3_IPL_IPC;
        IPC3bits.INT3IS         =       _INT3_SPL_IPC;
        IEC0bits.INT3IE         =       1;

        IEC0bits.INT4IE         =       0;
        IFS0bits.INT4IF         =       0;
        INTCONbits.INT4EP       =       edge;
        IPC4bits.INT4IP         =       _INT4_IPL_IPC;
        IPC4bits.INT4IS         =       _INT4_SPL_IPC;
        IEC0bits.INT4IE         =       1;

/*
IR sensor
*************
use ADC module channel 2
*/
        // Ensure that the pin associated with the analog channel is in analog
        // input mode, and select the channel in the input mux.
        AD1PCFG = ~(1 << channelNumber);
        AD1CHS = (channelNumber & 0xFFFF) << 16;
        AD1CON1 =       0; //Ends sampling, and starts converting

        //Set up for manual sampling
        AD1CSSL =       0;
        AD1CON3 =       0x0002; //Tad = internal 6 Tpb
        AD1CON2 =       analog_reference;

        //Turn on ADC
        AD1CON1SET     =       0x8000;

        //Start sampling
        AD1CON1SET     =       0x0002;

        //Delay for a bit
        delayMicroseconds(2);

        //Start conversion
        AD1CON1CLR     =       0x0002;

        //Wait for conversion to finish
        while (!(AD1CON1 & 0x0001));

        //Read the ADC Value
        analogValue    =       ADC1BUF0

/*
Compass
**********
use I2C module #5
*/

/*
Servos
********
use TIMER4 to create pulse
*/
       //timer 4 set clock period 20ms
       T4CON = 0x0060; // set prescalar 1:64
       TMR4 = 0;
       PR4 = 0x61A8;

        IFS0CLR = 0x10000;// Clear the T4 interrupt flag
        IEC0SET = 0x10000;// Enable T4 interrupt

        IPC4CLR = 0x0000001F;
        IPC4SET = (_T4_IPL_IPC << 2) | _T4_SPL_IPC;

        T4CONSET = 0x8000;// Enable Timer4

/*
Xbee
******
use UART1 as the USB-PC connection
*/
        p32_regset * ipc;    //interrupt priority control register set
        int irq_shift;

        // Initialize the receive buffer.
        flush();

        // Compute the address of the interrupt priority control
        // registers used by this UART

        ipc = ((p32_regset *)&IPC0) + (vec / 4);      //interrupt priority control reg set

        // Compute the number of bit positions to shift to get to the
        // correct position for the priority bits for this IRQ.
        irq_shift = 8 * (vec % 4);

        // Set the interrupt privilege level and sub-privilege level
        ipc->clr =     (0x1F << irq_shift);
        ipc->set = ((ipl << 2) + spl) << irq_shift;

        // Clear the interrupt flags, and set the interrupt enables for the
        // interrupts used by this UART.
        ifs->clr = bit_rx + bit_tx + bit_err; //clear all interrupt flags

        iec->clr = bit_rx + bit_tx + bit_err; //disable all interrupts
        iec->set = bit_rx;                                            //enable rx interrupts

        // Initialize the UART itself.
        //      http://www.chipkit.org/forum/viewtopic.php?f=7&t=213&p=948#p948
		// calculate actual BAUD generate value.
        uart->uxBrg.reg  = ((__PIC32_pbClk / 16 / baudRate) - 1);  
        uart->uxSta.reg = 0;

		//enable UART module
        uart->uxMode.reg = (1 << _UARTMODE_ON);

		//enable transmitter and receiver
        uart->uxSta.reg  = (1 << _UARTSTA_UTXEN) + (1 << _UARTSTA_URXEN); 

/*
Camera
*********
use UART2
*/
        p32_regset * ipc;    //interrupt priority control register set
        int irq_shift;

        // Initialize the receive buffer.
        flush();

        // Compute the address of the interrupt priority control
        // registers used by this UART
        ipc = ((p32_regset *)&IPC0) + (vec / 4);      //interrupt priority control reg set

        // Compute the number of bit positions to shift to get to the
        // correct position for the priority bits for this IRQ.
        irq_shift = 8 * (vec % 4);

        // Set the interrupt privilege level and sub-privilege level
        ipc->clr =     (0x1F << irq_shift);
        ipc->set = ((ipl << 2) + spl) << irq_shift;

        // Clear the interrupt flags, and set the interrupt enables for the
        // interrupts used by this UART.
        ifs->clr = bit_rx + bit_tx + bit_err; //clear all interrupt flags

        iec->clr = bit_rx + bit_tx + bit_err; //disable all interrupts
        
		//enable rx interrupts
		iec->set = bit_rx;

        // Initialize the UART itself.
        //
        //      http://www.chipkit.org/forum/viewtopic.php?f=7&t=213&p=948#p948
        // calculate actual BAUD generate value
		uart->uxBrg.reg  = ((__PIC32_pbClk / 16 / baudRate) - 1);
        uart->uxSta.reg = 0;

		//enable UART module
        uart->uxMode.reg = (1 << _UARTMODE_ON);
		
		//enable transmitter and receiver
        uart->uxSta.reg  = (1 << _UARTSTA_UTXEN) + (1 << _UARTSTA_URXEN);

/*
SD-Card
**********
use SPI module  and pin 4 for SS/CS
*/
  SPI2CON = 0;

  DDPCONbits.JTAGEN = 0;

  AD1PCFG = 0xFFFF;

  chipSelectPin_ = chipSelectPin;

  pinMode(chipSelectPin_, OUTPUT);

  PORTSetPinsDigitalOut(prtSCK, bnSCK);
  PORTSetPinsDigitalOut(prtSDO, bnSDO);
  PORTSetPinsDigitalIn(prtSDI, bnSDI);

  // set pin modes
  chipSelectHigh();

  // must supply min of 74 clock cycles with CS high.
  for (uint8_t i = 0; i < 10; i++) spiSend(0XFF);

  chipSelectLow();

  // command to go idle in SPI mode
  while ((status_ = cardCommand(CMD0, 0)) != R1_IDLE_STATE) {
    if (((uint16_t)millis() - t0) > SD_INIT_TIMEOUT) {
      error(SD_CARD_ERROR_CMD0);
      goto fail;
    }
  }
  
  // check SD version
  if ((cardCommand(CMD8, 0x1AA) & R1_ILLEGAL_COMMAND)) {
    type(SD_CARD_TYPE_SD1);
  } 
  else {
    // only need last byte of r7 response
    for (uint8_t i = 0; i < 4; i++) {
                status_ = spiRec();
        }

    if (status_ != 0XAA) {
      error(SD_CARD_ERROR_CMD8);
      goto fail;
    }
    type(SD_CARD_TYPE_SD2);
  }

  // initialize card and send host supports SDHC if SD2
  arg = type() == SD_CARD_TYPE_SD2 ? 0X40000000 : 0;

  while ((status_ = cardAcmd(ACMD41, arg)) != R1_READY_STATE) {
    // check for timeout
    if (((uint16_t)millis() - t0) > SD_INIT_TIMEOUT) {
      error(SD_CARD_ERROR_ACMD41);
      goto fail;
    }
  }

  // if SD2 read OCR register to check for SDHC card
  if (type() == SD_CARD_TYPE_SD2) {
    if (cardCommand(CMD58, 0)) {
      error(SD_CARD_ERROR_CMD58);
      goto fail;
    }

    if ((spiRec() & 0XC0) == 0XC0) {
                type(SD_CARD_TYPE_SDHC);
        }
    // discard rest of ocr - contains allowed voltage range
    for (uint8_t i = 0; i < 3; i++) spiRec();
  }
  chipSelectHigh();

/*
WIFI
******
use SPI module and pin 10 for SS/CS + INT1
*/
VN:F [1.9.22_1171]
Rating: 10.0/10 (1 vote cast)
VN:F [1.9.22_1171]
Rating: 0 (from 0 votes)

chipKIT Design Challenge Winners

  We are pleased to announce the winners of the chipKIT Platform Design Contest.

Winning Entries:

 

Level 1 Challenge

ck761 ROV Controller  http://www.youtube.com/watch?v=_24bMhLS7Wo&list=PLXPjvBuqmMX5DkKE8Ni0FNN7o-nwPIYUU ROV_ck761 Develop an original application using a chipKIT platform, an existing, known-working shield, and existing, known-working libraries. Participants will have the choice of using a chipKIT Max32, Uno32 or uC32 platform.

Level 2 Challenge

ck758    OLED Screen Controller Demo  http://www.youtube.com/watch?v=4x3swzNr14Y&list=PLXPjvBuqmMX6KYPXqucRqc8uklqbSP8iZ OLED_ck758 Develop an original application using a chipKIT platform and an existing shield where associated libraries are modified to exploit specific features of the chipKIT platform’s PIC32 device and associated peripherals. Participants will have the choice of using a chipKIT Max32, Uno32 or uC32 platform.

Level 3 Challenge

ck765    KEELOQ Shield  http://www.youtube.com/watch?v=NVPb-qaEu8k&list=PLXPjvBuqmMX6dKnPE-AY-IAW4HqxAhIfn Keeloq_ck765 Develop an original shield that will highlight the additional functionality of the PIC32 devices populating the chipKIT platform. Participants will have the choice of using a chipKIT Max32, Uno32 or uC32 platform.

How Winners Were Determined

Winning entries were determined through the use of a survey grading each application on:
  • Overall impression of application
  • Use of unique peripherals found on the target MCU
  • If developer modified or created a new library
  • Documentation on hardware, libraries and tutorials 
Congratulations to all who participated. You all did an amazing job!! Please visit the contest YouTube channel to view all entries at www.youtube.com/chipkitcontest     
VN:F [1.9.22_1171]
Rating: 0.0/10 (0 votes cast)
VN:F [1.9.22_1171]
Rating: 0 (from 0 votes)

ChipKIT BB32

This is an implementation of a  ChipKIT platform on a Solderless Breadboard, using the Microchip PIC32MX250F128B that is now available with a Bootloader preinstalled. This implementation is based on the Digilent ChipKIT DP32, but modified to make it cheaper, flexible and cost effective for Hobbyists and Students in 3rd World Countries such as my own. (Shipping costs and import duties can be crippling). The circuit uses the Right Hand side of a Standard Solderless Breadboard and is designed for the smallest possible footprint. This means that more than half of the breadboard, on the Left Hand side, is available for conducting experiments and constructing interface modules, as the image shows.

Hardware:

Here is a closeup of the circuit itself,  it should provide sufficient information for most people to be able to build the circuit, assuming they have built circuits on a Breadboard befor.  For the wiring I suggest solid core telephone cable. Offcuts or discarded cable can often be found  on building sites or during office renovations and provide several colours of insulation. CAT5 cable could also be used.  As this is a semi permanent installation on the Breadboard I recommend that the wires be cut and bent to size for a neat and reliable construction. Some notes on the components used:
  • The Voltage Regulator is a LM1117-33, the Pin marked Adj is actually the Ground Pin.
  • The Electrolytic Capacitor is a 10uF, oriented so that Positive goes to the Center Pin of the regulator.
  • The 10uF capacitor on the PIC32MX is a Low ESR tantalum capacitor, negative to Ground.
  • The 2 Capacitors on the 8Mhz Crystal are 22pF ceramics, but any close value should do, it may even oscillate without them on a breadboard.
  • All other Capacitors are 100nF (0.1uF) ceramics, any 100nF capacitors will do.
  • All Resistors are 1K with the exception of the one on the LDR which is 22K. (it forms a voltage divider so choose one that best matches your LDR Characteristics).

Features:

USB Power is regulated down to 3.3 Volts for the benefit of the PIC32MX Device. The Breadboard may be powered via USB or the ICSP Header, but it has no protection diodes. It is advisable not to power it via the ICSP Header when plugging it into a USB port.  If it is powered via the ICSP Header,  set the voltage to 3V3 only. A 5V rail is provided as the last row on the Right, to facilitate interfacing to 5V devices such as LCD Displays. This is unregulated 5V directly from the USB Header. The layout is orientated so that the 5V Tolerant PINS are located near to the 5V rail. The majority of the ChipKIT PINS are located to the Left of the device and are readily accessible by the empty portion of the Breadboard. This block of PINS includes the Analog Pins. An ICSP Header is included and serves several roles. It may be used to Install or Replace the Bootloader, Program the board with MPLAB or to connect a PICKit Serial Analyzer / Logic Analyser or UART Tool to assist in Experiments and Debugging. It is only permanently connected to the power bus, use temporary jumper leads to connect to  the appropriate breadboard rows, depending on your application. The LED’s are connected to ChipKIT PIN# 13 and 14, so that the Standard Arduino Blink Sketch and others should compile and run without modification. When addressed in MPLAB they are RB2 and RB3 respectively. The Prog Button is available for use in Sketches (User Programs) as ChipKIT PIN# 17 or RB4 in MPLAB. ChipKIT PIN Numbers are indicated on the Device and Repeated on the Breadboard. Users may find it useful to print out the above Image as a reference whilst using the board. The Key is as follows:
  • The Numbers correspond to ChipKIT PIN# not Microchip Port or Pin Numbers i.e. digitalRead(17) would read pin 9 (RB4) of the PIC32MX package, analogRead(A0) would read pin 24 (RB13).
  • Numbers in RED are 5V tolerant Pins.
  • Numbers in GREEN are both Analog and Digital capable PINS and will work with both the digitalRead() and the analogRead() functions.
  • Analog Channel numbers are shown on the Breadboard Overlay along with the corresponding Digital PIN numbers.
  • Numbers with a ~ symbol may be connected to the OC Registers and used as Hardware PWM PINS.

Software:

Digilent have kindly supplied a Zip file that contains all the files and Instructions  needed to update your MPIDE to support the ChipKIT DP32. The same files will work with this BB32 implementation. http://www.digilentinc.com/Data/Products/CHIPKIT-DP32/DP32_variant.zip It should not, however, be necessary to modify the MPIDE if you are running a newer test version.  I have used the BB32 successfully with both mpide-0023-windows-20130602-test and mpide-0023-windows-20130609-test. If you have a blank device, Digilent also provide a copy of the Bootloader .HEX file.  http://www.digilentinc.com/Data/Products/CHIPKIT-DP32/chipKIT_Bootloader_DP32.zip You will need a PICKit3 or better to install it on the Device, but it can be done with the Breadboard in situ by connecting the ICSP Header pins to the appropriate PIC Pins as follows:
  • Mclr to PIC PIN# 1
  • Dat to PIC PIN# 4 (Chipkit PIN# 11)
  • Clk to PIC PIN# 5 (Chipkit PIN# 12)
If you have a PICKit3 then you will already be familiar with MPLAB, but in a nutshell, start a blank project, select your device as PIC32MX250F128B, File->Import the bootloader.hex file. Set Programmer->PICKit3 and then use the Program Button in the toolbar to upload. Disconnect the PICKit, Plug in the USB cable and if all is well the device will enumerate and you will get a new hardware found notification. If windows requests a driver it is located in the MPIDE directory: C:\….\mpide-0023-windows-20130609-test\drivers\chipKIT Drivers It should install as a stk500 device.

Getting started:

Run MPIDE.EXE from the folder you unziped too. select the Board:

Tools->Board->ChipKIT-> ChipKIT DP32

then

Tools->Serial Port and select the Port that was created by the stk500 driver

When in Bootloader Mode LED2 (RED) will flash at ~ 4Hz To test the Hardware run this Sketch: BB32_test.pde //_________________________________________________________________ // //  BB32_Test.pde // //  C.A.Roper – 2013/07/17 // //  Hardware confidance test Software for the CHIPKit-BB-32 //  CHIPKit compatable Breadboard circuit based on PIC32MX250F128B. // //  Tests Digital Output to LED’s //  Teats Digital Input from Prog Button //  Tests Analog Input from LDR //  Tests Serial Output Via USB //  Tests Serial Input from USB //_________________________________________________________________ // int Last; int State; int Character; void setup() { Serial.begin(19200); pinMode(17, INPUT); pinMode(13, OUTPUT); pinMode(14, OUTPUT); } void loop() { if(Serial.available()) { Character = Serial.read(); if(Character == ‘1’) State = 1; else if(Character == ‘0’) State = 0; else if(Character == ‘t’ || Character == ‘T’) State = !State; } if(digitalRead(17)) { State = !State; } if(State != Last) { digitalWrite(13, !State); digitalWrite(14, State); Serial.println(analogRead(A0)); } Last = State; delay(250); } Whilst uploading LED1 (Green) will flicker. Press the Prog Button to toggle the LED’s and open the Serial console to see the ADC Reading and to issue commands. To return to Bootloader mode and upload other Sketches:
  1. Close the Serial Monitor if open.
  2. Press and hold the Prog Button.
  3. Press and release the Reset Button.
  4. Release the Prog Button.
The Green LED will go out and the RED LED will Flash. Thats it, all that remains is to have fun with your shiny new ChipKIT. Don’t forget to Join the ChipKIT community and  read about new ChipKIT developments and uses. Cheers Chris http://caroper.blogspot.com/
VN:F [1.9.22_1171]
Rating: 10.0/10 (3 votes cast)
VN:F [1.9.22_1171]
Rating: +1 (from 1 vote)

DIY chipKIT Board Using a Through-Hole SPDIP PIC32

Overview:

Certain varieties of Microchip Technology’s PIC32 Microcontrollers are available in Small Plastic Dual In-line Packages (SPDIP). This packaging makes it very easy to build up your own chipKIT board at home using common tools found in the home hobbyist/Maker workshop. Other 32-bit platforms would require specialized equipment to solder their fine pitch packaging to a custom board.

This post will demonstrate how to build up a chipKIT Platform onto a solderless breadboard using a PIC32MX250F128B 32-bit Microcontroller and some readily available components.

NOTE: This application uses a voltage provided off of the USB line. This is adequate for Low Power application such as blinking a single LED. However, most applications will require that you connect a separate power source to the Vin input of the Voltage Regulator such as a battery (shown at the end of this post). Excessive application power consumption could damage your USB port.

Components list:

The following components were used to complete this project

  • The TCHIP-USB-MX250F128B: Microchip PIC32MX250F128B in SPDIP package preprogrammed with the chipKIT USB Bootloader
  • Microchip MCP1702-3302E/TO: 3.3V LDO Voltage Regulator in TO-92 package
  • 8MHz Crystal Oscillator
  • 4 x 0.1uF Capacitors
  • 1 x 10uF Tantalum or Ceramic capacitor (note: needed for low ESR characteristics)
  • 2 x 36pF Capacitors
  • 1 x 130Ω Resistor
  • 4 x 10kΩ resistors
  • LED
  • 2 x SPST Tactile Switches
  • Some sort of way to connect a USB cable to the breadboard. I used a Sparkfun BOB-09614 USB-mini Breakout board 
COMPONENTS

Schematic:

schematic

Procedure:

Insert the PIC32MX250F128B into a solderless breadboard. Be sure to connect all of the Vdd (3.3V) and Vss (0V) signals as shown. Be sure to double check the datasheet pin diagram shown below:

VoltageBlock

power_ground

Note that some pins are not labeled as Vdd or Vss but will need to be connected to these voltages for the application to function. This includes pins related to USB and our Analog peripherals on the Microcontroller. Also note that the 3.3V Vdd signal will be coming off of our MCP1702 3.3V regulator. Connect the GND to a breadboard rail that will be dedicated to Vss and the Vout pin to a breadboard rail that will be dedicated to Vdd. Also connect a 0.1uF capacitor to the Vin and Vout pins to GND. The pin out diagram for the MCP1702 is shown below: MCP1702_pinout MCP1702

Next, the USB breakout board will be connected as follows:

  • Provide the Vin signal for the MCP1702
  • Connect the D- and D+ data lines
usb_MCP1702_Conn
usb_data

There is a Voltage Regulator on the PIC32MX250F128B Microcontroller that regulates internal voltage down to 1.8V to meet the requirement of the core. You don’t really have to worry about this other than you will need to connect a low ESR capacitor such as a Tantalum type to the Vcap pin on the Microcontroller to ground (Vss) as shown: vcap_pinout vcap

This particular version of the chipKIT Platform will use the PIC32MX250F128B’s on-chip USB peripheral instead of the standard way of doing things with the FTDI chip. Therefore, we will need to tell the PIC32 when to go into “bootloader” mode. In order to download a sketch, the PIC32 will need to be in this “bootloader.” To do this, two pushbuttons are used. One to RESET (turn on and off) the microcontroller and a second PROGRAM pushbutton that you will press down while the Microcontroller comes out of RESET. Coming out of RESET, the Microcontroller notices that the pin connected to the PROGRAM pushbutton has been driven HIGH (3.3V) and will automatically enter into “bootloader” mode.

The RESET pushbutton is connected to the MCLR (pin 1 of the Microcontroller) through a 10kΩ resistor that will limit current. The MCLR pin, when driven low, will cause the PIC32 to RESET. Therefore, another 10kΩ resistor is used to pull the line up to 3.3V that will keep the device out of RESET. One lead of the pushbutton is connected to this 3.3V signal and the other to Vss. Therefore, when the pushbutton is pressed, the Microcontroller will notice that the MCLR pin is driven LOW and will enter into RESET mode.

Similarly, the PROGRAM pushbutton is connected to the RB4 (pin 11) on the PIC32 through a current limiting 10kΩ resistor. However, this time the pin is held LOW through a 10kΩ pull down resistor since the a HIGH signal on this pin tells the Microcontroller to enter “bootloader” mode: pushbutton block pushbuttons

Finally, the USB bootloader is based off of an 8MHz external crystal oscillator. The oscillator is connected to the OSC1 and OSC2 pins on the PIC32 and 36pF capacitors are connected to each to ground as shown: oscillator_block oscillator

Next, I added a 130Ω resistor connected to pin 16 then to an LED connected to ground.

led

The final circuit should look something like this:

final circuit microB

To connect to a battery source, disconnect the Vin input to the MCP1702 from the USB connector and connect to the positive terminal of a battery as shown. Make sure that the battery’s negative terminal is connected to the Vss rail on your board.

battery_connection

Testing the Application:

To test the application, we will create a sketch to blink the LED on pin 16, connect the board through the USB, and download the sketch.

Download MPIDE (a FREE download) from the Install page and install it, and then follow these instructions.

  1. Open up MPIDE and create a new sketch with the following code:
  2. /*
      Blink
      Turns on an LED on for one second, then off for one second, repeatedly.
    
      This example code is in the public domain.
     */
    
    void setup() {
      // initialize the digital pin as an output.
      // Digital pin 24 has the LED connected to it
      //For more information including a pin diagram please visit www.chipkit.net/diy-chipkit-board
      pinMode(24, OUTPUT);
    }
    
    void loop() {
      digitalWrite(24, HIGH);   // set the LED on
      delay(1000);              // wait for a second
      digitalWrite(24, LOW);    // set the LED off
      delay(1000);              // wait for a second
    }
    
  3. Connect the application through the USB connector to your computer.
  4. If the driver is not installed successfully, you will need to manually install. The driver is located in the directory where you originally installed MPIDE. On my Window® Machine, I installed MPIDE to my C drive as follows:

  5. C:\mpide-0023-windows-20130426-test\mpide-0023-windows-20130401-test\drivers

  6. Once the device drivers are successfully installed, you are now ready to program the board.The PIC32MX250F128B chip is preprogrammed with the USB bootloader. The bootloader will only define which pin is used as the PROGRAM input (Pin 11 in this case) and which pins will flash to indicate that the device is indeed in bootloader mode. In this case, the LED indicator is defined as pin 7 on the PIC32MX250F128B Microcontroller. If you were to connect an LED to this pin as you did above for pin 16, the LED would flash rapidly when in “Bootloader” mode. In order to define which pin on the PIC32 will do what, we need to select a configuration in the MPIDE. We will be using an existing board definition file for the new Fubarino Mini platform.

  7. In the MPIDE, select Tools>Board>Fubarino Mini.The PIC32 will now be set up as follows: pinout

  8. You will need to make sure that the application is in Bootloader mode. To do this, hold down the PROGRAM pushbutton connected to pin 11 while pressing on/off the pushbutton RESET connected to MCLR (pin 1).

  9. Select Tools > Serial Port > COMx (whatever serial comm has been assigned to the application)

  10. Click the upload button in MPIDE.

  11. The application USB will disconnect and then the LED connected to Digital Pin 24 should start flashing.

To view the pinout configuration and to locate some relevant tutorials, please visit the Fubarino Mini homepage at www.fubarino.org/mini.

VN:F [1.9.22_1171]
Rating: 8.4/10 (22 votes cast)
VN:F [1.9.22_1171]
Rating: 0 (from 0 votes)

Arduino-style Maze Solving Robot using Sparkfun Ardumoto

OVERVIEW:

Here is a robot application that implements a very simple maze solving algorithm. This application uses off the shelf components along with a very basic chassis built from common materials. This could be a good weekend project. The robot chassis for this Demo was constructed with 2½” wide by ¼” thick poplar project wood purchased at a local home improvement center. Note that a box was also created to house the battery holder. mazebot

HARDWARE USED

CONSTRUCTION

The Ardumoto Shield is mounted to a chipKIT Uno32 Development Platform with all component connections made to the shield as indicated in labels next to component. mazebot_construction

LOGIC OVERVIEW

The maze solving theory used here is based on the following: Say you enter a maze or room, close your eyes, place your right hand on the wall, and start walking while keeping your hand on the wall. You will eventually find your way out of the room or maze. Not the fastest route, but it works! This assumes that all the walls are connected of course. Here is the basic software algorithm in flowchart form. A graphical representation of the robot and the sensors is on the right of the chart for reference.   Robot starts by checking its sensors. If it detects a wall on its side sensor, it checks to see if the wall is in its “Sweet Spot”. If so, the robot will adjust its wheel speeds to move in a straight line (supposedly parallel to the wall). If either the front or side sensor detects a wall that is too close, then the robot turns off its left wheel so that it veers to the left (hopefully avoiding a collision). Otherwise, the robot will move in a wide circle to the right with the hopes that an object will come into view of at least one of the sensors.   Note: You can also use the left side to do this.   mazebot_overview  

 SKETCH

 
/*
 9/10/2012
 Marc McComb

This code runs a maze solving routine based on the following:
Say you enter a maze or room, close your eyes, place your right hand on the wall, and start walking while keeping your hand on the wall. 
You will eventually find your way out of the room or maze. Not the fastest route, but it works! This assumes that all the walls are connected of course

So the robot starts by checking its sensors. If it detects a wall on its side sensor, it checks to see if the wall is in its “Sweet Spot”. If so, the robot
will adjust its wheel speeds to move in a straight line (supposedly parallel to the wall). If either the front or side sensor detects a wall that is too close,
then the robot turns off its left wheel so that it veers to the left (hopefully avoiding a collision). Otherwise, the robot will move in a wide circle to the
right with the hopes that an object will come into view of at least one of the sensors. 

This application uses the following hardware:
chipKITâ„¢ Uno32 available at http://www.digilentinc.com/chipkit 
Sparkfun Ardumoto - Motor Driver shield: https://www.sparkfun.com/products/9815
Some Sharp GP2Y0A21YK0F IR Sensors - Available at Adafruit with wires already attached: https://www.adafruit.com/products/164

Software used:
The Ardumoto board is designed for a PWM on pin 11. Since the Uno32 doesn't have a hardware PWM on that pin, no worries, we just
use Brian Schmaltzs SoftPWMServo library:
http://www.chipkit.org/wiki/index.php?title=Library_Status#SoftPWMServo_library 

You will need to make sure that you add the library. To do this:
1) Make sure that you have a folder in your Documents:/MPIDE folder called Libraries
2) Copy the SoftPWMServo library folder from C:\mpide-0023-windows-20120903\hardware\pic32\libraries to the Libraries folder above
3) If MPIDE is open, close and reopen. 
4) Now all you have to do is go to the MPIDE toolbar and select Sketch>Import Library>SoftPWMServo

More info on libraries at:
http://arduino.cc/en/Reference/Libraries

*/

//Need to use this library instead of just analogWrite() since there pin 11 isn't a PWM pin on the chipKIT UNO32 board.
//No big deal. This library works great on almost any pin. 
#include <SoftPWMServo.h>

//MOTOR SETUP
const int pwm_a = 3;   //PWM control for motor outputs 1 and 2 is on digital pin 3
const int pwm_b = 11;  //PWM control for motor outputs 3 and 4 is on digital pin 11
const int dir_a = 12;  //direction control for motor outputs 1 and 2 is on digital pin 12
const int dir_b = 13;  //direction control for motor outputs 3 and 4 is on digital pin 13
const char motor_speed = 200; //set the motor speed (between 0 and 255)

//IR SENSOR SETUP
const int rSensor_pin = 0; //right sensor will be read on ANO
const int fSensor_pin = 5; //front sensor will be read on AN5

//Let's set up some variable that we'll use in the code
int rSensor_val = 0;  //this will be the right sensor value ADC reading (between 0 and 1023)
int fSensor_val = 0;  //this will be the front sensor value ADC reading (between 0 and 1023)
boolean sweetspot = false;  //boolean value initialized to false. When its true, it means the wall on the right of the robot is the "sweet spot"
boolean rSensorHit = false; //boolean value initialized to false. When its true, it means the wall on the robot's right is too close
boolean fSensorHit = false; //boolean value initialized to false. When its true, it means the wall in front of the robot is too close 
int sensor_state = 0;

void setup()
{
  pinMode(dir_a, OUTPUT); //Set the dir_a pin as an output
  pinMode(dir_b, OUTPUT); //Set dir_b pin as an output
  digitalWrite(dir_a,  HIGH);  //Reverse motor direction, 1 high, 2 low
  digitalWrite(dir_b, HIGH);  //Reverse motor direction, 3 low, 4 high  

}

void loop()
{ 

  //This is how I usually do things but you may wish to change it up a bit

  //First get all you inputs
  read_sensors();
  //Then make some decisions based on these inputs
  parse_inputs();
  //Then do all your outputs at the same time. In this case, determine motor speeds
  run_motors();
  //I always have a loop timing function
  loop_timing();
}

//this function reads the IR value on the analog input pins
void read_sensors()
{

  rSensor_val = analogRead(rSensor_pin);
  fSensor_val = analogRead(fSensor_pin);
}

//this function then makes decisions based on those inputs
void parse_inputs()
{

  if (fSensor_val > 850) fSensorHit = true; //if the front sensor sees a wall set the fSensorHit variable TRUE

  //Otherwise, check if the robot is in the "sweet spot"
  else if ((rSensor_val > 750)&&(rSensor_val <850)&&(fSensor_val < 850)) sweetspot = true;      //If not, then is the wall on the right side of the robot too close?   //If so, set the rSensorHit variable TRUE   else if (rSensor_val > 850) rSensorHit = true;

  //Otherwise make sure all of the sensor flags are set to FALSE
  else{
    fSensorHit = false;
    rSensorHit = false;
    sweetspot = false;
  }

  //reinitialize your sensor variable to a known state
  rSensor_val = 0;
  fSensor_val = 0;

}

//This routine runs the two motors based on the flags in the previous funciton
void run_motors()
{

  //If the wall on the right is too close, turn left away from the wall
  if (rSensorHit)left(); 

  //Otherwise, if the wall is in the "sweet spot", then try and stay parallel with the wall
  //keeping both wheel speeds the same
  else if (sweetspot)forward();

  //If the front sensor sees a wall, turn left 
  else if (fSensorHit)left();

  //If neither sensor sees a wall, then move in a really big arc to the right. 
  //Hopefully, the bot wil be able to pick up a wall
  else right();

  //Always set your flags to a know value. In this case, FALSE
    fSensorHit = false;
    rSensorHit = false;
    sweetspot = false; 

}

void loop_timing()
{
  delay(50);

}

//Motor routines called by the run_motors()

void forward() //full speed forward
{ 

  //both wheels spin at the same speed 
  SoftPWMServoPWMWrite(pwm_a, motor_speed); 
  SoftPWMServoPWMWrite(pwm_b, motor_speed);
}

void stopped() //stop
{ 

  //turn off both motors
  SoftPWMServoPWMWrite(pwm_a, 0);
  SoftPWMServoPWMWrite(pwm_b, 0);
}

void left()                   //stop motor A
{

  //turn of the left motor so that the robot vears to the left
  SoftPWMServoPWMWrite(pwm_a, motor_speed);
  SoftPWMServoPWMWrite(pwm_b, 0);

}

void right()                   //stop motor B
{ 

  //Here we're running the right motor at a slower speed than the left motor
  //Therefore, the bot will travel in a large circle to the right
  SoftPWMServoPWMWrite(pwm_a, 50);
  SoftPWMServoPWMWrite(pwm_b, motor_speed+50);  
}
 
VN:F [1.9.22_1171]
Rating: 8.8/10 (8 votes cast)
VN:F [1.9.22_1171]
Rating: 0 (from 0 votes)

Efficient Use of C++ in Embedded Systems

Those of you planning to begin a project in using C++, hopefully using the MPLAB XC32++ compiler or the chipKIT platform, already know about the object-oriented programming concept of polymorphism. Essential to polymorphism is the concept of a virtual method, a method whose behavior can be overridden within an inheriting class by a method with the same signature.

Virtual methods are implemented using a virtual method table (vtable). The compiler creates a vtable for each class. When an object is created, a pointer to this table is added as a hidden member of the object. The compiler also generates code to initialize the vpointers of its objects to the address of the corresponding vtable. When designing your classes for your embedded application, you will want to keep the extra overhead of the vtable in mind.

Along the same lines, as an embedded-systems developer, you may be surprised by the overhead required by a pure virtual method, since it has no implementation and can therefore never be called directly. Well, the compiler generates error-handling code to handle the case where a pure virtual function is called. In the current XC32 v1.20 compiler release, when a pure virtual method is called, an error message is printed and a C++ exception is thrown, bringing in a fairly large amount of code that should never be executed. While the error handling is useful, we plan to look into simplifying it in future compiler releases to reduce the overhead. For now, you will find that avoiding a pure virtual method will help keep your code size down.

A pure virtual method assigns the function the value 0 rather than providing an implementation. For example:

class Base
{
public:
const char* SayHi() { return "Hi"; } // a normal non-virtual method
virtual const char* GetName() { return "Base"; } // a normal virtual method
virtual int GetValue() = 0; // a pure virtual method
};

To avoid the extra overhead, provide a default implementation like this:

class Base
{
public:
const char* SayHi() { return "Hi"; } // a normal non-virtual method
virtual const char* GetName() { return "Base"; } // a normal virtual method
virtual int GetValue() { while(1); /* Error */ } // a normal virtual method
};

Another hidden consumer of Flash space to look out for is Run-Time Type Information (RTTI). This C++ mechanism exposes information about an object’s data type at runtime. The dynamic_cast<> operation and typeid operator are part of RTTI. When this feature is enabled, additional the type information gets stored in Flash and can consume space even when the application does not use it. When you’re not using RTTI, be sure to disable it in your project settings (-fno-rtti). This compiler option can be added to the chipKIT IDE (MPIDE) default compiler option in <install_dir>/hardware/pic32/platforms.txt

C++ exception handling also causes additional code to be generated. Although exceptions provide a way to react to exceptional circumstances (like runtime errors) in an application, they come at a fairly substantial code and data memory cost. When your application doesn’t require exception support, you can disable it in your project settings (-fno-exceptions). This option is specified by default when the chipKIT IDE (MPIDE) invokes the chipKIT compiler.

[ Thanks to Jason Kajita for this helpful information ]
VN:F [1.9.22_1171]
Rating: 9.3/10 (4 votes cast)
VN:F [1.9.22_1171]
Rating: 0 (from 0 votes)

NKC ProtoShield Kit for chipKIT Uno32

This article describes an expansion board kit available from NKC Electronics for the chipKIT Uno32 Development Board.

What is a Proto Shield? We all know that the Shields are from the Arduino world and they are named after the little boards that sits on top of the Arduino and compatible boards. A Proto Shield is a combination of a ProtoBoard with a Shield. You usually use a Bread Board to build a prototype, to test the design. Once you have it working and want to house it in a more permanent board, is where a Proto Shield shows its benefits.

The ProtoShield for the chipKIT Uno32 is an exclusive design of NKC Electronics, and it has many nice features:

NKC_protoshield_image_1

The fully assembled ProtoShield board looks like this:

NKC_protoshield_image_2

The kit includes the board and many extra components. What you finally end up installing on the ProtoShield will be based on your requirements. But in general, I recommend soldering all the female headers, as they are needed to bring all the signals and POWER from the chipKIT Uno32 board to the ProtoShield.

NKC_protoshield_image_3

The LED with the associated resistor and filtering capacitor is to add a POWER indicator, meaning you have 5V power from the chipKIT Uno32 board to the ProtoShield.

NKC_protoshield_image_4

The RESET switch is necessary if you want to reset the chipKIT Uno32 board from the top.

NKC_protoshield_image_5

The little 6-pin male header with the 2 jumpers are used to configure how you want to use the 2 power BUSES in the middle of the board. You can send +5V to one of them, GND to the other, or +5 or GND to both of them at the same time.

NKC_protoshield_image_6

If you use the 6-pin male header jumpers to power the BUS, then you can only have +5V.

If you need the full ProtoShield to be 3.3V, then you can select one of the jumpers to GND and the other one open and connect +3.3V directly to the positive BUS. Take a look at the diagram below:

NKC_protoshield_image_7

For more information, visit NKC Electronics Protoshield Kit for chipKIT Uno32

VN:F [1.9.22_1171]
Rating: 0.0/10 (0 votes cast)
VN:F [1.9.22_1171]
Rating: 0 (from 0 votes)