Since it has a rocket shape, I had the idea to build a custom flame shaped PCB for the output LEDs, which I could plug through the 2x5 pins BSL connector.
The board itself is open source hardware and has an MSP430F5510 microcontroller, where most of the pins are available through 2 rows of pads. It also comes with a mini USB port, 2 buttons for reset and bootloader mode, and 2 LEDs connected to GPIOs:
I plugged the board to my PC and the LEDs blinked, but it is a BSL Loader and I want to turn it into an EMF detector so it was time to start modifying the firmware. The best way to get started with the rocket is by checking its info on the Texas Instruments Wiki.
Once installed, confirm the license agreement. To try it out first I chose the blink LED example, but before upgrading the firmware, the board must be detected, and for that it needs to start in Bootloader mode. That can be done either by powering the board or pressing the reset switch, while holding the Bootloader button (USB_BSL). After that, the program should detect the device and the "Upgrade Firmware" option will become available.
Now that I tested downloading something to the board, it's time to start thinking about the EMF detector. A few years ago I had seen an Arduino EMF detector on Make, originally made by Aaron ALAI. So I thought about doing something similar. First thing I'm going to need is an analog input, so by checking the MSP430F5510 datasheet, I see that the PT package, which is the one used on the rocket, has 6 external ADCs, where 4 of them are in the pins P6.0 to P6.3. According to the rocket schematic, these pins are free and available on the pads, so I'm going to use one of them for my antenna.
More specifically, I'll be using pin P6.2 which corresponds to the ADC A2. Using a 3 MΩ pull-down resistor and a piece of wire for the antenna:
That only leaves behind V3.3, GND and TVCC_SENSE. This last one just goes to a normal pad on the rocket, but the power pins gave me an idea. I could mount a battery pack behind the flame PCB and power the entire rocket with it, this way it could be a portable EMF detector, which is exactly what it should be.
Having figured out the pins that I was going to need, I moved on to the actual application. For that I'll be using Code Composer Studio from Texas Instruments. It has a few different licensing options, but for this project, the free license it's all you need.
After selecting the workspace, you're greeted with the Getting Started page, which has a few interesting options, like training, videos and examples, which are particularly useful if you're using CCS for the first time.
I started by browsing the examples, there you can select the family of microcontrollers and then choose the examples you want, each one demonstrates the usage of a different peripheral, like GPIOs, ADCs, Timers, Comparators, UART and SPI Communications, among others. Since my idea for the EMF detector was to "read the environment" through an ADC pin and light up the LEDs forming some kind of a bar effect, the ADC and GPIO examples should come in handy.
Before moving on to the actual EMF application, let's start off by compiling the Toggle LED example, which is the first one on the resource explorer list, and try uploading it to the board. This application configures pin P1.0 as an output and toggles its state through a software loop.
By checking the MSP430-BSL Rocket schematic, we can verify that this pin is actually being used for the green LED on the board (which is why the earlier blink LED example also worked!). So it should do just fine without any changes to the code. However, the MSP430 Firmware Upgrade Example application, uses a specific format to upload the code to the board, which is the TI TXT format. To have that file, first we need to tell CCS to generate that specific output file format when building the project. To do so, on the project explorer section, right click on the desired project and select properties. Then navigate to "CCS Build > MSP430 Hex Utility" and select the checkbox "Enable MSP430 Hex Utility", a few more options will appear bellow. Now on the navigation tree, go to "CCS Build > MSP430 Hex Utility > Output Format Options" and then select the Output Format: "Output TI-TXT hex format (--ti_txt)".
I'm using CCS version 6.0.1, so the procedure might be slightly different for other versions. After doing this, every time you build the project, in the main directory, inside the Debug folder, there will be also a TXT file, which is the TI TXT hex format file, and this is the one you'll upload to the board if you are using the MSP430 Firmware Upgrade Example. There, you'll have the option to download your custom firmware, select the generated TXT file and click on "Upgrade Firmware".
And we can see that it works:
Now I'm ready to finally move on to the EMF application. I started by connecting all the 7 GPIOs from the BSL connector to LEDs on a breadboard using a few wires:
Then I developed a simple application to light up all the outputs, one at a time, to check that all of them were working properly:
From studying the GPIO, ADC and Timer examples, I was able to develop the basic structure of the EMF Detector. I thought it would be cool to make the rocket's green and orange LEDs toggle every 0.2 seconds, to let me know that the detector was working, even when the EMF measurement is not enough to light the first flame LED, besides it would be a great opportunity to use timers and interrupts. But first some basic bitwise operations. For this, Ray Wisman has a good and simple explanation on his MSP430 Getting Started guide:
Now for the code, first comes the main configurations like defining the ADC channel, the auxiliary functions, initializing the ports and some variables:
#include "msp430f5510.h" #define ADC_Channel ADC10INCH_2 // ADC PIN P6.2 float ADC_Result; // ADC Value _Bool ADC_Ready; // ADC Done flag _Bool Timer_Ready = 0; // Variable to toggle the LEDs with a timer void measure(unsigned int); void initTimer(float); void main(void) { WDTCTL = WDTPW+WDTHOLD; // Stop WDT P1DIR |= BIT0; // Set P1.0/Green LED to output direction P1DIR |= BIT1; // Set P1.1/Orange LED to output direction PJDIR |= 0x0F; // Set PJ.0 to PJ.3 to output direction P4DIR |= 0xFF; // Set P4 to output direction P1OUT |= BIT0; // Set P1.0 to 1 P1OUT &= ~BIT1; // Set P1.1 to 0 ADC_Ready = 0; // Variable to indicate ADC is ready initTimer(0.2); // Start the timer clock - receives seconds
The main loop will check if either the timer or ADC interrupts are ready and react accordingly. If the timer has run out, the Rocket LEDs will toggle their state, if the ADC conversion is ready, then the output flame LEDs should turn on accordingly with the voltage level:
for (;;) { __delay_cycles(100); // default is 5000 measure(ADC_Channel); __bis_SR_register(CPUOFF + GIE);// LPM0, ADC10_ISR will force exit if (Timer_Ready) // Timer runs out { Timer_Ready = 0; P1OUT ^= BIT0; // Toggle LED - XOR P1OUT ^= BIT1; // Toggle LED - XOR } if (ADC_Ready) // ADC conversion is ready { ADC_Ready=0; ADC_Result=ADC_Result*3.3/1023; // Convert into Volts if (ADC_Result < 0.665) // All off { PJOUT = 0x00; P4OUT = 0x00; } else if (ADC_Result < 0.67) // P4_4 on { PJOUT = 0x00; P4OUT = 0x10; } else if (ADC_Result < 0.69) // and P4_5 { PJOUT = 0x00; P4OUT = 0x30; } else if (ADC_Result < 0.73) // and PJ_2 { PJOUT = 0x04; P4OUT = 0x30; } else if (ADC_Result < 0.79) // and P4_0 { PJOUT = 0x04; P4OUT = 0x31; } else if (ADC_Result < 0.85) // and PJ_1 { PJOUT = 0x06; P4OUT = 0x31; } else if (ADC_Result < 0.98) // and PJ_3 { PJOUT = 0x0e; P4OUT = 0x31; } else // and P4_3 { PJOUT = 0x0e; P4OUT = 0x39; } } } }
The auxiliary functions are responsible for configuring the timer and the ADC:
// Initialize Timer - see from page 474 slau208n void initTimer(float time) { // Configure Timer TA0CCR0 = 32768*time; // Value for timer to compare TA0CTL = TASSEL_1+MC_1+TACLR; // ACLK, count to CCR0, clear TAR TA0CCTL0 = CCIE; // Gen interrupt when rollover } // ADC configuration - see from page 711 slau208n void measure(unsigned int channel) { // Configure ADC ADC10CTL0 |= ADC10SHT_2 + ADC10ON; // ADC10ON, S&H=16 ADC clks ADC10CTL1 |= ADC10SHP; // ADCCLK = MODOSC sampling timer ADC10CTL2 |= ADC10RES; // 10-bit conversion results ADC10MCTL0 |= channel; // A3 ADC input select; Vref=AVCC ADC10IE |= ADC10IE0; // Enable ADC conv complete int. ADC10CTL0 |= ADC10ENC + ADC10SC; // Sampling and conversion start }
And then their respective interrupt service routines:
// ADC10 interrupt service routine #pragma vector=ADC10_VECTOR __interrupt void ADC10_ISR (void) { ADC_Result = ADC10MEM0; // Saves measured value. ADC_Ready = 1; // Sets flag for main loop. __bic_SR_register_on_exit(CPUOFF);// Enable CPU so main loop continue } // Timer0 A0 interrupt service routine. #pragma vector=TIMER0_A0_VECTOR __interrupt void TIMER0_A0_ISR (void) { Timer_Ready = 1; // Time to update __bic_SR_register_on_exit(LPM3_bits); // Exit LPM }
After building the project with CCS and downloading the application to the rocket with the MSP430 Firmware Upgrader, it was time to test it out. I pulled out an extension cord near to the antenna of the EMF detector and there it was, the LEDs started shining:
Having tested the general concept I could move on to the actual flame PCB. So I opened up KiCad and started drawing the schematic:
I decided to use an extra connector for the battery pack to power the entire detector, and a 10 pin IDC10S/PCB Male connector to plug in the flame directly to the MSP Rocket. Then it was time to start drawing the PCB itself. First I tried to visually design the rocket as realistic as I could, to be able to have a good visual reference of how large the flame should be. Then I sketched the flame and added the LEDs and connectors:
Since the MSP Rocket already has 100Ω resistors on the BSL connector, and the board is going to work on 3.3V or less, I concluded it wasn't necessary to add any more. After the design was ready, I moved on to the etching phase:
I used the Toner transfer method to pass the circuit onto the PCB and then used a solution of acid and hydrogen peroxide for the corrosion part. After that the double sided PCB was ready:
Unfortunately the PCB that I used was a bit old and oxidated so it didn't turn out quite perfect, but still it didn't have any major problems (at least on the tracks):
Then I protected the connector pads and painted the PCB yellow. Now it's becoming more like a flame:
I painted some contours with a black pen, giving the flame a cartoony look and soldered the LEDs and connectors into place:
Then I added the battery pack on the back of the PCB. Fortunately, the MSP430 is a very low power microcontroller, which makes it one of the best to use in battery powered applications. This way 2xAAA batteries should be more than enough to power the EMF detector for a good while. I guess this is sort of a booster pack:
Microwave:
Now obviously the calibration is a bit messy and it's kind of hard to make it work as well in strong electromagnetic fields as in weak fields. Besides, the proximity of the antenna wire to the USB port on the rocket also has an influence, because it's ground shielded. Either way it was a fun project, and even though it's not the most precise thing there is, it still allows for some really interesting discoveries around the house or the lab.
By the way, if you want to restore the original MSP430 BSL Rocket firmware, you can find it here.
And also, if you want a TI launchpad, I'm selling some of mine here.
So thanks again for this prize Texas Instruments Europe!
No comments:
Post a Comment