Recently I attempted to use an Adafruit PowerBoost 500C to power a small MCU-based mobile robot. Specifically, I wanted it to:
Supply 5v to the system out of a 3.7v LiPo battery.
Charge the battery like if it was a smartphone
Shut power down when wheels get stuck, and
Trigger an interrupt software when battery is low.
It is this last which gave me some problems. Documentation states the Low battery (LB) pin goes to ground when the battery voltage drops below 3.2v. That sounds just fine, except that there are many things that can make the battery voltage drop briefly below 3.2v, specially as it gets closer to the “low battery” point. In this specific case, even though the battery was “decently” charged, motors running would make the LB pin flicker between High and Low, thus generating a train of false interrupts. As the battery continued to discharge, the flickering continued and the Low LED in the PowerBoost board became brighter. I suspect the duty-cycle of the flickering (so to speak) increased. (I might be wrong on this, a quick look in the oscilloscope would dissipate doubts, but who has time for that). From this explanation, the solution is simple: a low-pass filter. One just needs to adjust the cut-off frequency to let only the low-battery flickering pass, and not those generated by the motors when the battery is still charged.
Low-pass filter solution
My first solution was to filter the flickering in software, and it worked fine. The problem was that no matter what the MCU was getting interrupted no less than 15 times in a second when charged. My second solution was to use a RC filter, with the RC filter I was able to reduce the number of false interrupts to around 1 to 2 per second when charged. (I’m not an expert on this matters, and I’m guessing with the right RC values, the flickering can be entirely removed. Either way, 1 to 2 times per second was good enough for me, and I did not have capacitors of other values at hand.) Then I simply filtered the 1 to 2 false interrupts using the built-in de-bounce filter in the SAM4S and an old trick used for de-bouncing buttons by checking ,waiting, and checking again (a bunch of nested if statements and delays)… after that no more false interrupts.
It’s really just one resistor and a capacitor. I used a 1 uF capacitor and 22 kohms resistor. This tutorial shows more information about it. It even shows the cut-off frequency equation to find the right values for R and C.
Recently I was in need to get two separate UARTS from the SAM4S Xpro board. It took me a while, but I finally figured out how to use the USART1 with interrupts; and since I already had working code for UART1, I decided to post examples for both.
UART1 is exposed in pins 13 and 14 in EXT3, and also in the Debug USB port. It requires the UART – Univ. Async Rec/Trans (driver) ASF module. For this example I’m using the code from here, without any modification.
USART1 is exposed in pins 13 and 14 in EXT1 and EXT2. It requires the USART – Univ. Synch Async Rec/Trans (driver) ASF module. Other modules that may be using it must be removed, or else you get a USART1_Handler redefined error. Most of the code for this example is from the ASF documentation, but it was missing a configuration step of USART1 pins. Also it had what it seemed to be a mistake; in the call to usart_init_rs232, I replaced sysclk_get_main_hz() for sysclk_get_peripheral_hz(), and that fixed it. The working code is in the downloads.
I recently acquired an Atmel BNO055 Xplained Pro board, which features a 9-axis absolute orientation sensor, or at least that is the part I’m interested in. Then I found that the ASF does not provide BNo055 support for the SAM4S. Luckily, it does for the SAM E70. So I adapted the SAM E70 drivers to work with the SAM4S, and surprisingly it worked without any issues.
Note that the drivers in the ASF are a port from the ones provided by Bochs (BNO055 chip manufacturer).
In the downloads you will find an Atmel Studio 7 solution. The /ASF/ThirdParty/bno055 folder contains the driver’s source code, and /config/conf_bno055.h is the configuration file. It is tested for ASFv3.34.1.
The downloads also include three examples. motion_example.c demonstrates how to configure the sensor in low power mode. That is, when no motion is detected the sensor’s MCU goes to sleep, and, when it detects movement (while sleeping), it wakes up and interrupts the main MCU (SAM4S in this case). orientation_example.c configures the sensor in normal mode (no interrupts) and reads orientation values. Lastly, motion_and_orientation.c is a combination of the two, and demonstrate how to read the sensor only when it is awake.
Reading other output data
Like I mentioned above, I was not interested in anything other than orientation values, but it is possible to query the sensor for other fused and non-fused data (e.g. raw accelerometer data). I have not test them, but the SAM E70 example was using these:
If Edison had a needle to find in a haystack, he would proceed at once with the diligence of the bee to examine straw after straw until he found the object of his search. ... I was a sorry witness of such doings, knowing that a little theory and calculation would have saved him ninety per cent of his labor