ChipKIT - Getting Used to It
by GastonLagaffe in Circuits > Microcontrollers
2488 Views, 9 Favorites, 0 Comments
ChipKIT - Getting Used to It
YAAC - Yet Another Arcuino Clone?
So I got a chipKIT Lenny and it looks like just another of those Arduino clones. So what is it good for and why not getting a normal Arduino? Why bother with 3.3V? What is this Program key about? Can I use it like the Arduino I already have?
All those questions came to my mind when I first stumbled into a chipKIT board. I had used the Arduino for quite some time and was running into its limitations of speed and memory. I also wanted to dive deeper into the world of microcontrollers and be able to design and build the board all by myself.
I have found kits that allow me to build an Arduino clone but due to the limitations of the design, I was not able to get a board done that connects directly to my PC. I always had to use an FTDI Adapter or revert to SMD parts I cannot solder myself.
On my search in the internet I came arcoss a guide on how to build a board similar to the Arduino on a breadboard with full USB access to the PC. Well, breadboard means you can create a printed circuit board (PCB) and solder this by yourself. And there is a pre-loaded chip available that allows you to use a nice IDE. With the release of chipKIT core, I can even use the Arduino IDE.
So why switch to a differnet design? Well, lets have a look at the features of the chips:
Feature | Arduino | chipKIT breadboard | chipKIT Lenny |
---|---|---|---|
Chip | ATmega328 | PIC32MX250f128B | PIC32MX270f256D |
Flash Memory | 32 kB | 128 kB | 256 kB |
SRAM | 2 kB | 32 kB | 64 kB |
Speed | 16 MHz | 48 MHz | 48 MHz |
Serial Port | 1 | 2 | 2 |
I2C | 1 | 2 | 2 |
SPI | 1 | 2 | 2 |
I/O Voltage | 5 V | 3.3 V | 3.3 V |
Form-Factor | Arduino | free selectable | Arduino |
So with chipKIT I have more resources to play with and I can design my own PCB - but 3.3V
3.3 Volt? You must be kidding!
I am not. But when I started I was worried about not destroying my chip with 5V inputs and the Arduino Due shows, that the 3.3V voltage was not adopted by the Arduino community in the beginning. So some time ago, 3.3V was an issue. With the raspberry pi that has changed. the raspberry pi is on 3.3V too so today, you can get everything for that voltage level and a lot of breakouts are 3.3V/5V agnostic. As long as you send signals out, the 3.3V level is not an issue as the receiving 5V device understands the 3.3V logic levels.
The only danger is incoming signals with 5V. Especially analog pins do not like to be fried on 5V. But you get sued to it and the mitigation that are available (voltage divider, levleshifter). I will come to this later in the examples.
But 3.3V has its advanatges: LiPo rechargeable batteries come with 3.7 V - just enough to drive my board if needed, simplifiying a lot of use cases. Of course, the battery voltage should be connected to a proper power circuit that uses a voltage regulator to generate the clean 3.3V for the chip. Never connect the battery directly to the chip as the voltage can go up to 4.2V on such a battery if fully charged. (Thanks to MikeL90 who pointed that out in the comments)
Two UART, I2C, SPI - so what?
Having two busses of each kind comes in handy if you have two devices that share the same identification on that bus. That is quite neat with I2C and gives you plenty of options if your first SPI bus is busy with a SPI attached display.
To me, the biggest surprise was the additional serial ports: Originally I was fine with the serial port that comes with the USB connection, just a bit annoyed as with the Arduino that you have to close the serial port before uploading new code. And under Windows, the serial ports could get locked up with this, requiring you to restart the IDE.
Now with the chipKIT device, the serial port, that gets started over the USB line, is assigned to its own port number. So I can have my Terminal Program open and send code to the board in the meantime - that is very convenient!
But the additional UART (Serial) ports were extremely useful once I started working with Bluetooth modems like the HC-05/HC-06. On the Arduino, the USB connection blocks the serial pins that are used to talk to the bluetooth device. This turned out to be very inconvenient and made using bluetooth a nightmare (at least for me).
With the chipKIT boards, you have 2 independent UARTS/Serial ports. This allows you to connect your bluetooth or ESP8266 device to one of these ports and still be able to upload your sketch and use the standard serial port.
So forget Arduino?
Not at all! I still have my collection of Arduinos and use them once in a while. However, with the possibilities that opened up with chipKIT, my Arduinos gather quite some dust ...
The idea of this instructable is to take you on a tour around the chipKIT boards. Perhaps you develop an appetite like I did to create your own board or play with the Lenny if you come from the Arduino. Once you mastered this, you might get interested in the entire family of chipKIT boards - but one step at a time ...
The Tour
In this instructable I will introduce two chipKIT boards:
- the chipKIT Lenny - Arduino form factor
- the HelvePic BreadBoardSide - a board that you can solder yourself and clip it into the side of a breadboard
I will describe all the features that these boards offer out of the box and that completes this instructable.
In subsequent instructables I will then expand the description to describe how to use peripheral breakouts like
- TFT displays,
- OLEDs and
- LED matrices.
Finally I will show how to readout sensors by going through the elements of one of these "37 sensors kits" available from many sources
But first lets take a look at the two boards I am talking about
The ChipKIT Lenny by Majenko Technologies
Arduino Compatibility
The chipKIT Lenny is designed to be as close to the Arduino Leonardo as physically possible. The choice of microcontroller, the PIC32MX270F256D with advanced Peripheral Pin Select, means GPIO pin functions can be mapped to match those of common Arduino boards. By default that mapping is configured to be equivalent to the Arduino Leonardo.
PIC32 Power
With considerably more Flash and SRAM than the Arduino Leonardo the chipKIT Lenny gives your program room to breathe and expand. Open up new horizons with advanced high-speed peripherals. Dual SPI ports, both of which support I2S audio codec interfacing opens the door to high quality audio processing. Direct control over the USB interface allows you to emulate keyboards, mice, serial connections and more. The 40MHz default configuration (may be increased to 50MHz) lets you do considerably more calculations and operations in a shorter time.
USB Connectivity
A direct USB connection allows the chipKIT Lenny to appear as a wide range of different devices to your computer. If you want a traditional serial connection you can have a traditional serial connection. If you want to make a special keyboard the computer can see it as a normal system keyboard. If you want to make a mouse controlled by your hamster you can make the computer recognise it as a standard mouse.
FastProg Technology
Unlike other USB-based chipKIT boards, the Lenny includes FastProg technology. For USB-based chipKIT boards it is traditional to enter the bootloader for reprogramming the board using a tricky two-button combination. With FastProg this has been reduced to simply pressing one button. The FastProg circuit takes care of all the rest for you. No more squeezing fingers into tight spaces to access the buttons in the right order. Just press-and-go.
chipKIT Lenny by Majenko Technologies on Sketchfab
The Details
Microcontroller: | PIC32MX260F256D-50I/ML |
Flash: | 256KB |
SRAM: | 64KB |
Speed: | 40MHz (switchable to 48MHz) |
GPIO: | 27 |
Analog Inputs: | 6 |
PWM Outputs: | 5 |
Interrupt Inputs: | 5 |
SPI Ports: | 2 |
I2C Ports: | 2 |
UART Ports: | 2 |
Power Input: | 5V (USB) or 6.5V to 12V (DC Input) |
I/O Voltage: | 3.3V |
The full manual can be downloaded here.
The HelvePic BreadBoard Side
The HelvePic32 BreadBoard Side - short: BBSide
Inspired by the work of a friend with breadboard, I started to use breadboard as well and did not lik at all the mesh of wires that connect my controller board, being it an Arduino or the Lenny, to the breadboard. Of course there are plenty of boards that you can clip on to the center of the breadboard like the Arduino Nano or the chipKIT fubarino. But these boards consume quite some space on the breadboard and I still have a mesh of wires connecting the boards to the parts that I have to place on the side of the clipped-in board.
This launched the idea of having a board that you can clip into the side of a breadboard. TGhis would leave the entire opposite side to parts without connecting them immediately to the pins of my board - the HelvePic32 BreadBoard Side was born.
Understanding my board
The next step was to understand what I put on that board. I am a physisict and love to get to the details of a design. So I started with the minimal configuration I needed to get the board going:
The Schematic
The schematics shows how simple the chipKIT board can be: There is the microcotroller with its 28 pins. To the right side, there are the header pins so we can connect the controller chip to the rest of the world. Above the chip, there is a small EEPROM chip with a small 100nF capacitor to smooth the power supply voltage.
The chipKIT controller needs two tactile switches to change its operation mode: The RESET button and the PROGRAM button. If the controller is reset and comes back on, it checks if the PROGRAM button is pressed. If that is the case, it goes into bootloader mode awaiting new code - otherwise it starts the code that is already loaded. These two buttons are shown above the chip with some pull-up resistors.
Then there are four LEDs with their current limiting resistors. The three LED, that are connected to pins, have a solder bridge so you can detach the LED if it interfers with your pin usage.
Above all, there is a standard power supply setup with two voltage regulators, one for 5V and one for 3.3V. There lis alos a Crystal that is needed by the controller to operate at a defined frequency and a 10 uF capacitor that stabilizes a special voltage.
The remaining two items to mention are the USB connector and the 4.7 kOhmpull-up resistors for the I2C lines.
And we are done!
So on a PCB this looks like the follwing pictures:
The core chip circuits
The power bank
The peripherals
The EEPROM
DYI - build your own board
The BBSide was created after a sequence of boards that started with a Through Hole design (PTH) that can be soldered by almost anybody including young children from the age 12-14 (under supervision by na adult as we operate with hot soldering irons at 300-400 degrees C).
In a later step I changed the Through-Hole DIL chip to the SMD chip with more pins (TQFP44) but that is not easy to solder and requires a lot of experience.
But there is also a chip version with the package size SSOP-28W - and that can be soldered by hand with some exercising. The comparison of the chip pin spacing with the 0.1" header spacing shows that this kind of SMD parts are easy to solder.
Soldering SMD - no way!
When I first thought about soldering SMD parts I was convinced I could not solder them by hand. But today, I prefer to design my boards all on SMD parts. Of yourse not this tiny form factors 603 or smaller! but 1206 or 805 are sizes, that you can solder easily. Any finally, it becomes much more convenient to solder these parts than through hole with its bending the wires, flipping the board, soldering, checking it had not moved, cliping the wires ... not to mention the hassle to remove or replace a part in through hole setup.
The parts I use are pretty large and the trickiest part is the processor with its SOIC28 package. But on that package, the pins of the chip are almost as far apart as the pins of a header:
So I made a video on how to solder this board and it takes about 15 minutes from start to finish.
Interested?
The board can be ordered from aisler.net
You can get the board alone or with a parts set.
Flashing a PIC32 Chip
What is a bootloader?
When you write your code in the Arduino IDE or the UECIDE, the programming software has to talk to a code on the chip that understands a transfer protocol or you have to use a programmer tool like the Pickit3. On the Arduino, this is commonly done via the ISP connector on the board.
Arduinos and chipKIT boards like the chipKIT Lenny come with a bootloader already loaded onto the chip and ready to talk with your IDE to load the sketches.
Wen you build your own board with your own chip, there is no bootloader on that chip, so you have to flash the bootloader first.
This sounds more complicated than it is.
Loading the bootloader
Once done with the soldering of the kit, you have to load the bootloader to the chip, which is done through a programmer called Pickit3, available for 10-20 USD over the internet. Connect the tool as follows:
To program the chip you need to download and install the MPIDE software from microchip. You do not need to install the compiler at the end of the installation process, as we do not use them, All we need is the MPLAB IDE to flash the chip. This is the icon on your screen I am talking about:
With the Pickit3 connected and the chip family and processor selected, the initail screen looks like this:
On my PC, the initial connection to the chip fails and I have to disconnect the Pickit3 from the USB port to get it going. The picture here shows the failed connection and the successfull connect afterwards:
Now we select the source for the bootloader. It is a 16kB file that you can download from this page.
Pushing the Program button will flash the bootloader to the chip.
If not sure, you can verify that the source and the bits on the chip are the same.
The best feature compared to the Arduino is the fact, that teh Pickit3 can also read a bootloader that is already on the chip and store it to a file. That makes playing with bootloaders absolutely risk free, as you can save the working bootloader and flash your version. It is not working, just reload the original bootloader.
Any by the way - no fiddling with fuses etc ...
Downloads
Programming the Boards
Using the Arduino IDE
You are familiar with the Arduino IDE? Fine, all you have to do is to add the chipKIT Core to the boards similar as we do it of the ESP8266 family or the DigiStump boards. In the preferences you have to add the link to the chipKIT Core to the list of board managers:
<a href="https://github.com/chipKIT32/chipKIT-core/raw/master/package_chipkit_index.json">https://github.com/chipKIT32/chipKIT-core/raw/mast...</a>
The Arduino IDE entry looks like this:
Using the UECIDE
Alternatively you can use the UECIDE from http://uecide.org - a IDE that is much nicer than the Arduino IDE, but that is just my personal view. When you install the IDE you are asked to select the boards you want to use. The IDE looks like this screen:
As the screenshots have been taken on the same PC, you can see that both IDE can exist side-by-side.
In the subsequent publications I will use the UECIDE as it is my preferred IDE
Explore the Boards
In a frist approach to the boards, lets check what we have on the board without any additional kit.
Talk to the board
The first thing to encounter is the possibility to talk to the board from the PC. This is done through the serial interface that is built in the USB connection and that can easily be activated.
int val;//define variable val<br>void setup() { Serial.begin(9600); // set the baud rate at 9600 to match the software set up. pinMode(PIN_LED1,OUTPUT); // initialize digital PIN_LED1 as output. When using I/O ports this kind of set up is always needed. } void loop() { val=Serial.read(); // read the instruction or character from PC to chipKit, and assign them to Val. if(val=='R') // determine if the instruction or character received is “R”. { // if it’s “R”, digitalWrite(PIN_LED1,HIGH); // set the LED on digital pin 13 on. delay(500); digitalWrite(PIN_LED1,LOW); // set the LED on digital pin 13 off. delay(500); Serial.println("Hello World!"); // display“Hello World!”string. } }
As with any sketch, there are the two routines
void setup()and
void loop()
, where setup is executed once at the start of the execution and lopp is called continuously.
In setup we initialize the serial port to talk with a speed of 9600 baud - that is not fast but ok for the moment. The second statement tells the controller to use a pin PIN_LED1 for output.
In the loop, we check if there is something coming from the serial port and if so, we light up the LED, wait 500 milli seconds, shut down the led and print a message to the Serial port.
The variable PIN_LED1 we did not define. This is due to the fact, the the two boards we look at have three LEDs on the board and the variable is already defined for the boards.
The digitalWrite routine takes care to set the state of the PIN_LED1 to either HIGH (the LED is on) or LOW (the LED is off)
More blinking LED
As any Arduino tutorial starts with a blinking LED we will do so as well. The chipKIT Lenny and the HevlePic BBside have both three LEDs on the board, called PIN_LED1, PIN_LED2 and PIN_LED3. So the standard blink sketch will look like this:
void setup() {<br> pinMode(PIN_LED1,OUTPUT); pinMode(PIN_LED2,OUTPUT); pinMode(PIN_LED3,OUTPUT); } void loop() { digitalWrite(PIN_LED1, HIGH); digitalWrite(PIN_LED2, HIGH); digitalWrite(PIN_LED3, HIGH); delay(1000); digitalWrite(PIN_LED1, LOW); digitalWrite(PIN_LED2, LOW); digitalWrite(PIN_LED3, LOW); delay(1000); }
You spot the similarity to Arduino code? Well, that is intentionally! Programming the chipKIT boards is just like Arduino. Jou just need to take into account that the chipKIT boards are on 3.3V.
As long as the signals are outgoing, the 3.3V signals have the same effect as the 5V signals as the 5V boards treat anything above ~2.7V as HIGH.
Manipulate some bits
To continue with the similarities between Arduino and chipKIT, we are no doing some bit operations. We will increment a counter step by step and on the byte we use to store the value, we will test if one of the bits is high. Is bit 1 set, we will light LED1, for bit 2 we use LED2 and for bit 3 we use LED3:
uint8_t counter = 0; void setup() { pinMode(PIN_LED1,OUTPUT); pinMode(PIN_LED2,OUTPUT); pinMode(PIN_LED3,OUTPUT); } void loop() { digitalWrite(PIN_LED1, counter & 0b00000001); digitalWrite(PIN_LED2, counter & 0b00000010); digitalWrite(PIN_LED3, counter & 0b00000100); delay(1000); counter++; }
You may spot that for the counter we are using uint8_t instead of the commonly used int or byte.
This is good programming practice as the way, and integer (int) is stored, depends on the processor platform. On the Arduino being an 8-bit processor, an int is 8 bits, on the chipKIT platform being 32-bit processors, an int is 32 bit.
By using uint8_t you are more precise in what you want as variable: an Unsigned INTeger of 8 bits and it is a Type.
This works on the Arduino as well any you should consider writing your code always like that.
In the digitalwrite command we then test if th bit is set by using the bitwise AND with its operator "&".
A traffic light
Now having three LED gets me the idea to deomstrate the lights as they change with a traffic light. The for loop in the setup routine is simulating the warning by a flashing yellow light when staring the traffic light
uint8_t LED_Red = PIN_LED3; uint8_t LED_Yellow = PIN_LED2; uint8_t LED_Green = PIN_LED1; void setup() { pinMode(PIN_LED1,OUTPUT); pinMode(PIN_LED2,OUTPUT); pinMode(PIN_LED3,OUTPUT); digitalWrite(LED_Red, LOW); digitalWrite(LED_Yellow, LOW); digitalWrite(LED_Green, LOW); for (int i=0; i<5;i++){ digitalWrite(LED_Yellow, LOW); delay(1000); digitalWrite(LED_Yellow, HIGH); delay(1000); } } void loop() { digitalWrite(LED_Red, HIGH); digitalWrite(LED_Yellow, LOW); digitalWrite(LED_Green, LOW); delay(6000); digitalWrite(LED_Red, HIGH); digitalWrite(LED_Yellow, HIGH); digitalWrite(LED_Green, LOW); delay(2000); digitalWrite(LED_Red, LOW); digitalWrite(LED_Yellow, LOW); digitalWrite(LED_Green, HIGH); delay(6000); digitalWrite(LED_Red, LOW); digitalWrite(LED_Yellow, HIGH); digitalWrite(LED_Green, LOW); delay(2000); }
The Push Button
We conclude our tour with looking at the program button of the HelvePic BBSide: It is connected to pin4 and used to get the board into bootloader mode. But once a sketch is running, we can use this button as part of our sketch.
On the chipKIT Lenny, the PROG button is connected to the reset button and pushing the button will get you straight into bootloader mode. So this last example is for the HelvePic BBSide only:
As this botton comes with the board, it is defined as the LEDs with a pre-defined variable PIN_BTN1
int val;// define val<br>void setup() { pinMode(PIN_LED1,OUTPUT);// set LED pin as “output” pinMode(PIN_BTN1,INPUT);// set button pin as “input” } void loop() { val=digitalRead(PIN_BTN1);// read the level value of pin 7 and assign if to val if(val==LOW)// check if the button is pressed, if yes, turn on the LED { digitalWrite(PIN_LED1,LOW); } else { digitalWrite(PIN_LED1,HIGH); } }
In this example you can see, that the pinMode of the button pin is INPUT as we expect this button to be read by the code. In the loop routine we do exactly this and read out the state of the button. Once it is pressed, we switch on the LED.
Using Serial Ports
You certainly know the Serial port that is so common to be used for debugging. What annoys me on the Arduino is that I have to close the serial monitor (I use TeraTerm) to be able to send code to the Arduino and if I want to use a bluetooth modem, it gets so complicated that most people revert to a software serial port.
Not so with the chipKIT Lenny and the HelvePic BBSide!
We have 3 serial ports!
There are three serial ports on both boards:
- Serial - the one well known and provided over the USB cable
- with chipKIT, the serial port that is opened, once the serial line is started is on a different port than the one, the bootloader opens. This is extremely nice as you can leave the serial terminal open while you send code to the board
- Serial0 - also known as UART1
- on the Lenny, RX is pin D0 and TX is pin D1
- on the BBSide, RX is pin 7 and TX is pin 3
- Serial1 - also known as UART2
- on the Lenny, RX is pin D4, TX is pin D2
- on the BBSide, RX is pin 13 and TX is pin 10
So for a test of the serial ports, I connected two FTDI breakouts to Serial0 and Serial1 and had all three TeraTerm windows open next to each other. The following code mirrors the input from one Terminal to the other two:
/* Multiple serial port test (For chipKIT) any data received from a serial port is echoed to the other two ports */ long broadcast = 0; void setup() { // Open serial communications and wait for port to open: Serial.begin(9600); Serial0.begin(9600); Serial1.begin(9600); while (!Serial) { ; } } void loop() // run over and over { char c; if (millis() > broadcast){ broadcast = millis() + 10000; Serial.println("Serial : Serial Port test broadcast"); Serial0.println("Serial 0 : Serial Port test broadcast"); Serial1.println("Serial 1 : Serial Port test broadcast"); } if (Serial.available()){ c = Serial.read(); Serial0.write(c); Serial1.write(c); } if (Serial0.available()){ c = Serial0.read(); Serial.write(c); Serial1.write(c); } if (Serial1.available()){ c = Serial1.read(); Serial0.write(c); Serial.write(c); } }
This code is a nice tool to check that all serial ports are ok and that you have not accidently mixed RX and TX, as they always need to be corssed. So RX on the FTDI goes to TX on the board and TX on the FTDI goes to RX on the board. You will find this out rather quickly ...
What are they good for?
When you connect a bluetooth modem like the HC-05 to the board, you can connect a Smartphone to the bluetooth modem and use a little app called remoteXY to drive your board remotely! The code is generated via a browser application
I created a simple joystick interface and the code to read the joystick is pretty easy:
#define REMOTEXY_MODE__HARDSERIAL #include <remotexy.h> #define REMOTEXY_SERIAL Serial0 #define REMOTEXY_SERIAL_SPEED 9600 #pragma pack(push, 1) uint8_t RemoteXY_CONF[] = { 255,2,0,0,0,12,0,8,13,0,5,0,35,17,30,30,2,26,31 }; // this structure defines all the variables of your control interface struct { // input variable int8_t joystick_1_x; // =-100..100 x-coordinate joystick position int8_t joystick_1_y; // =-100..100 y-coordinate joystick position // other variable uint8_t connect_flag; // =1 if wire connected, else =0 } RemoteXY; #pragma pack(pop) int8_t last_x = 0; int8_t last_y = 0; void setup() { RemoteXY_Init (); Serial.begin(9600); } void loop() { int8_t current_x; int8_t current_y; bool changed = false; RemoteXY_Handler(); current_x = RemoteXY.joystick_1_x; current_y = RemoteXY.joystick_1_y; if (current_x != last_x){ changed = true; last_x = current_x; } if (current_y != last_y){ changed = true; last_y = current_y; } if (changed){ changed = false; Serial.print("Joystick 1 x : \t"); Serial.print(last_x); Serial.print("\tJoystick 1 y : "); Serial.println(last_y); } }
How does it work?
The code waits until there is a bluetooth remote connection with the app on the smartphone. It then sends the contents of
RemoteXY_CONF[]
to the Smartphone that defines the joystick and its position. In the loop() routine, the call to
RemoteXY_Handler()
waits for you to do somehting on the Smartphone and returns the new joystick position. The code afterwards only checks if there was a change in the position and if so, it prints the values on the Serial interface.
So with a few lines of code, you get a remote control to your project with chipKIT!
Conclusion and Next Instructable
So this first instructable comes to its end. We have taken a short tour on the two boards and went through the first set of examples that are used in the Arduino tutorials as well to get you started.
I hope it became clear that the chipKIT world and the Arduino world are very similar and close to each other. Code from the Arduino world can usually be used on chipKIT boards as well. You only run into some more work to port the code if Arduino specific low-level functions like the internal timers are used. But in these cases, there are usually adjusted libraries that take care of this.
So what´s next?
The next step is to look at peripherals, especially sensors. For that I got me one of these "37 sensor in on kit" boxes. In the next instructable, I will go through these sensors and show how to use this with the chipKIT Lenny and the HelvePic BBSide.
So I currently plan three instructables:
- 37 sensor in one kit
- displays (TFT, OLED, e-paper)
- motors (motor, servo, stepper)