chicken

Members
  • Content count

    860
  • Joined

  • Last visited

  • Days Won

    69

Everything posted by chicken

  1. I don't try to convince anybody. I'm way too busy myself to unlearn bare metal C. But I thought the video will be relevant for people that venture down the rabbit hole.
  2. Here's some more C++ magic which seems applicable to embedded programming. I think he optimized for speed instead of space (using tons of mov instead of a loop to initialize sprite bitmaps). But a lot of impressive optimization by the compiler. On the downside, I didn't understand half the constructs he was using. I guess I need to relearn C++ via embedded.fm podcast
  3. On the profile page it is labeled as "content count". Maybe "posts" includes status updates and other content.
  4. no need to start another thread
  5. In my project, I use a few basic macros for GPIO. The goal is, that I can easily redefine pin assignment in a central location without compromising performance or code size. The macros (gpiomacros.h): // MSP430 gpio macros #define GPIO_SEL(port) P ## port ## SEL #define GPIO_DIR(port) P ## port ## DIR #define GPIO_OUT(port) P ## port ## OUT #define GPIO_IN(port) P ## port ## IN #define GPIO_IS_INPUT(port,pin) { GPIO_SEL(port) &= ~(pin); GPIO_DIR(port) &= ~(pin); } #define GPIO_IS_OUTPUT(port,pin) { GPIO_SEL(port) &= ~(pin); GPIO_DIR(port) |= (pin); } #define GPIO_IS_PERIPHERAL_IN(port,pin) { GPIO_SEL(port) |= (pin); GPIO_DIR(port) &= ~(pin); } #define GPIO_IS_PERIPHERAL_OUT(port,pin) { GPIO_SEL(port) |= (pin); GPIO_DIR(port) |= (pin); } #define GPIO_SET(port,pin) { GPIO_OUT(port) |= (pin); } #define GPIO_CLEAR(port,pin) { GPIO_OUT(port) &= ~(pin); } #define GPIO_READ(port,pin) ( GPIO_IN(port) & (pin) ) In a central configuration file (e.g. hardware.h) I assign pins like this: // Pin assignment #define LED1_PIN BIT1 #define LED1_PORT 6 #define LED2_PIN BIT0 #define LED2_PORT 1 And then in the code I interact with GPIO like this: // Setup LEDs GPIO_IS_OUTPUT(LED1_PORT, LED1_PIN); GPIO_IS_OUTPUT(LED2_PORT, LED2_PIN); // Turn off LEDs GPIO_CLEAR(LED1_PORT, LED1_PIN); GPIO_CLEAR(LED2_PORT, LED2_PIN); The macros are resolved in two steps: 1. Higher level "functions" define the commands. E.g. GPIO_SET(), GPIO_IS_OUTPUT(), .. 2. Lower level macros used within those functions translate port, pin to a register. E.g. GPIO_IN(), GPIO_SEL(), .. The end result is code like you would write when directly working with the GPIO registers. E.g. P2OUT &= ~BIT0; Note that this translation is done by the C pre-processor before the code is compiled. This all works fine and dandy, with the exception of port J. Port J doesn't have a SEL register, which breaks the 1st half of the GPIO_IS_OUTPUT and GPIO_IS_INPUT macros. I currently work around this by adding special GPIO_IS_OUTPUT/INPUT_J macros, but then the main code needs to include some logic to invoke the proper macro. #if (LED2_PORT == J) GPIO_IS_OUTPUT_J(LED2_PORT, LED2_PIN); #else GPIO_IS_OUTPUT(LED2_PORT, LED2_PIN); #endif Any ideas, how I could include a condition inside macros, that checks whether the port is J, and if so excludes the GPIO_SEL command? And yes, I could probably use C++ templates with identical results and an easy workaround for port J, but I'd like to avoid migrating my plain old C project. Edit: Added a few missing parentheses, thanks to Rickta59 for spotting that
  6. Is there a specific event when you must read the ADC? If not, just make one main loop that reads keys and ADC. Reading the ADC should only take a fraction of a second.
  7. I don't know how good those books by Make are, but if you're looking for some beginner books for Arduino and Raspberry Pi and don't mind that you only get a digital copy (PDF, ePUB or MOBI), this might be of interest: Humble Book Bundles: Arduino & Raspberry Pi https://www.humblebundle.com/books/make-arduino-and-raspberry-pi $1 bundle: Make: magazine, Volume 38: Everything you need to know about DIY consumer electronics Make: Basic Arduino Projects Making Things See: 3D vision with Kinect, Processing, Arduino, and MakerBot Make: Getting Started with the Internet of Things Make: Getting Started with Netduino $8 bundle adds: Make a Mind-Controlled Arduino Robot Make: A Raspberry Pi-Controlled Robot Make: AVR Programming Make: FPGAs Make: Bluetooth $15 bundle adds: Make: Getting Started with Arduino, 3rd Edition Make: Getting Started with Raspberry Pi, 3rd Edition Make: Getting Started with Sensors: Measure the World with Electronics, Arduino, and Raspberry Pi Make: Raspberry Pi and AVR Projects Make: Arduino Bots and Gadgets Make: Sensors Make: Getting Started with the Photon: Making Things with the Affordable, Compact, Hackable WiFi Module
  8. Did you already try the MSPFlash library that comes from Energia? Use search on this site to get plenty of threads about RTC, like for example this one: http://forum.43oh.com/topic/3375-energia-library-msp430-real-time-clock/
  9. How do you expect the JTAG programmer to provide a UART bridge when it's not connected to UART pins of the MCU? One the MSP430F5529 LaunchPad, a second UART is broken out on pins 3 and 4 (P3_3/P3_4). So unless your board has those broken out, using the CCS debugger is your only option.
  10. Overview dAISy (do AIS yourself) is a very simple AIS receiver that I developed from scratch. It is built around the Silicon Labs EZRadioPRO Si4362 receiver, using a Texas Instruments MSP430G2553 MCU for processing and the MSP-EXP430G2 v1.5 LaunchPad as development platform. The complete project source code and schematics are available on GitHub: https://github.com/astuder/dAISy Update 5/18/2015: A finished, self-contained AIS receiver based on this project is now available for purchase on Tindie. AIS, short for Automatic Identification System, is a standard for tracking ships. Ships advertise their position, course and other information with short transmissions on specific frequencies (161.975 MHz and 162.025 MHz). More on Wikipedia. An AIS receiver, like dAISy, receives and decodes AIS transmissions. It then re-packages the raw data into NMEA sentences (specifically formatted ASCII strings). Finally, using a serial connection, these strings are forwarded to more capable equipment for further processing. If you're the lucky owner of a tricked out boat, you could connect dAISy to your navigation computer. For land lobbers like me, a more common use case is to run naval mapping software that supports AIS data input on a PC. In the screenshot below I've connected dAISy to OpenCPN (link), an open source chart plotter and navigation software. On the top right you can see my setup war-driving at the Seattle waterfront as my lab is too far from the coast to receive anything. The LaunchPad sits on the dashboard with a white USB cable connecting to the notebook computer in the foreground. dAISy's data is fed into OpenCPN, bottom right shows a log of the serial data received. OpenCPN maintains a database of all the collected data (lower left) and visualizes nearby ships on a map (top center), including past and projected course. Hovering the mouse over a ship will display its name (text on yellow ground) and clicking it will reveal more detail (top left). Hardware I wanted to build my own, non-SDR, AIS receiver for a long time. There are a few projects floating around the internet (e.g. here) which refer back to an article by Peter Baston, published 2008 in Circuit Cellar magazine (copy available here gone.. google for Peter Baston Circuit Cellar to find other copies). Unfortunately, the CMX family of modem ICs by CMS Microcircuits (link) used in these projects are relatively expensive ($15+) and hard to find for hobbyists. In addition you'd need a radio to do tune into and down-convert from the ~162 MHz carrier frequency. So I was quite excited when earlier this year a parametric search on Mouser brought up a new IC that covered the required range (162 MHz) and modulation (GMSK). And best of all, available in single quantities for $3.56 $2.27 $2.22! (link) The Silicon Labs EzRadioPRO Si4362 (link) is a single chip receiver that covers frequencies from 142 to 1050 MHz and supports various modulations, including GMSK. It comes in a tiny 20-pin QFN package and the only external parts required are a 30 MHz crystal, an antenna with a few capacitors and inductors for impedance matching, and finally some decoupling caps and pull-down resistors. Time to whip up a breakout board. I used the opportunity to give KiCad a try and quite like it. Here's the schematic: And the layout: I used OSHPark to make the PCBs. At a smidgen over one square inch it cost $5.15 for 3 copies: http://oshpark.com/shared_projects/QUWi71r4 Note that the layout still has three issues that I already fixed in the schematic: GPIO0 and GPIO1 were flipped SDO required a pull-down resistor as the radio leaves it floating when not actively sending, which confused the hell out of me while trying to figure out the communication protocol. Lastly, the holes for the headers turned out to be slightly too small to comfortably fit the cheap breakout headers I had at hand. Edit: Here's Rev B where I fixed these issues: http://oshpark.com/shared_projects/WI6u3Qmk Which brings us to the BOM: Silicon Labs Si4362 (U1) 30 MHz crystal (X1)Si4362 datasheet specifies <11 pF load capacitance, but a crystal specified for 12pF load capacitance seems to work fine too Antenna/LNA matching network, calculated based on SiLabs AN643 (link, approx. values, +/- 5% shouldn't matter too much):75 ohm (dipole): 10 pF (CR1), 5 pF (CR2), 280 nH (LR1), 200 nH (LR2) 50 ohm: 12 pF (CR1), 6 pF (CR2), 240 nH (LR1), 160 nH (LR2) Decoupling caps:100 pF, 100 nF, 1uF (C1, C2, C3) Pull-down resistors100 k (R1, R2) First thing I noticed when I received the parts: The 20-pin QFN at 4x4 millimeters is tiny! I mounted it by first tinning the pads with a small quantity of solder. I then added flux and placed the chip on the pad. I then used a hot air station to carefully reflow the solder. Worked the first time around. After using jumper wires to figure out how to talk to the chip, I mounted the breakout board on a makeshift BoosterPack using perfboard, double-sided tape and wire (see picture at the top of the post). Here's how I ended up connecting the breakout board to the LaunchPad / MSP430G2553: SEL -> P1.4 (SPI chip select) SCLK -> P1.5 (SPI CLK) SDO -> P1.6 (SPI MISO) SDI -> P1.7 (SPI MOSI) GPIO0 -> P2.0 (I/O unused) GPIO1 -> P2.1 (I/O clear-to-send) GPIO2 -> P2.2 (I/O RX clock) GPIO3 -> P2.3 (I/O RX data) SDN -> P2.4 (shutdown / reset) IRQ -> P2.5 (I/O channel-clear) Software The software of dAISy consists of three major blocks: Radio configuration and control over SPI Packet handler, including a basic FIFO for received messages NMEA encoding and transmission to the PC over UART For UART (TX only) and SPI (TX/RX) I use the MSP430G2553's USCI A0 and B0 respectively. In both cases I don't use interrupts which simplifies things considerably. Upon reset the following steps happen: Initialize MSP430 peripherals Initialize packet handler, which will also reset FIFO Initialize and configure of radio, which will also setup SPI Start packet handler, which will also put the radio into receive mode And in the main loop: If debug messages are enabled, poll packet handler for status and errors and report them over UART Check FIFO for new packets If there is a new packet, invoke NMEA processing (which sends the message over serial to the PC) and remove packet from FIFO Below follows a more detailed discussion of the radio integration and the implementation of the packet handler. Radio The communication with the radio is vanilla SPI using 4 wires: MOSI (SDI), MISO (SDO), CLK (SCLK) and CS (SEL). I used the MSP430's USCI B0 to implement SPI and a separate pin to control CS. The only tricky thing to figure out was, that the Si4362 keeps the MISO line floating unless it actively transmits data. This is unfortunate as the master is supposed to poll for a specific response (FF) to detect when the radio is ready to receive more commands. This is easily fixed by adding a weak pull down resistor to SDO. I did this on the board, but it probably also works with using MSP430's internal pull-down. Additional lines I used to control the radio are: SDN to reset the radio CTS, which by default is mapped to the radio's GPIO1, indicating that the radio is ready for the next command While taking up an extra pin, CTS turned out to be much more convenient than the SPI response code to properly time communication flow with the radio. In dAISy, I wait for CTS to go high after each command to ensure the radio completed its task. The communication protocol is quite extensive but well documented: EZRadioPRO API Documentation describes the complete API and all registers AN633 Programming Guide for EZRadioPro Si4x6x Devices describes how to use the API in common scenarios Both are available on the Si4362 product page (link), under Documentation > Application Notes and are still updated quite frequently. The radio is set up by dumping a large configuration sequence into it. This includes configuration of radio frequency, modulation, GPIO pins and more. This information is stored in radio_config.h, which has to be generated with a tool called WDS (Wireless Development Suite). WDS is available in the Tools section on the Si4362 product site. Above are the settings I used for dAISy. WDS will use this information to configure various amplifiers, filters, clocks and decoding algorithms inside the chip. As Si4362 supports GMSK encoding only indirectly (see this thread), I'm certain there's more optimization potential by tweaking registers, but that's currently way beyond my knowledge of RF theory. While the Si4362 comes with its own packet handler, it unfortunately does not support NRZI encoding (Wikipedia). So I set up the radio to expose the 9600 baud clock and received data on separate pins and implemented my own packet handler. Packet Handler The packet handler (inspired by Peter Baston's implementation) is implemented as a state machine that is invoked on each rising edge of pin P2.2 which receives the data clock. There are 5 main states: Off, no processing of incoming data Reset, start from anew, either on start up or after successful/failed processing of a packet Wait for Sync, waiting for a training sequence to arrive (010101..) and start flag (01111110), implemented with its own state machine Reset, start new preamble 0, last bit was a zero 1, last bit was a one flag, training sequence complete, now process start flag Prefetch, ingest the next 8 message bits to ease further processing Receive Packet, process bits until the end flag (01111110) is found or an error situation occurs Independent of state, the interrupt routine continually decodes NRZI into actual bit sequence. In the "Receive Packet" state there's continuous calculation of the packet CRC and some bit-de-stuffing. When the end flag is found and the CRC is correct, the received message is committed into the FIFO. If an error is encountered, the bytes already written to the FIFO are discarded. In both cases, the state machine starts anew by transitioning into RESET. This reads like a lot of code for an interrupt handler. However with the MCU running at 16MHz even the most complex state only uses a fraction (<10%) of the available time. Future Improvements Lastly a list of things I'd like to improve with the next version of dAISy. Software: Receiving on both AIS channels through channel-hopping done 1/5/2014 Tweak radio settings for better sensitivity and lower error rate LED(s) for indicating reception of valid/corrupt packets Hardware: Proper antenna connector Layout PCB as BoosterPack and/or USB dongle Receiving on both AIS channels at once with two radio ICs -- edit 12/25: replaced original post with high-level project description, more detailed documentation of implementation to come -- edit 12/28: added documentation for hardware (here and on Github), fixed some typos -- edit 12/31: added documentation for software and list of future improvements -- edit 01/05: implemented channel hopping (change to state machine) -- edit 01/15: changed state machine to reflect recent changes (see post further down for details), added link to shared project on OSHPark -- edit 01/25: major rework of sync detection state machine
  11. @@nazmibojan thanks for reporting back. Great idea to get a cell phone repair shop to do the trickier soldering work :-)
  12. How long are the wires over which you want to do I2C? Are the grounds connected? Weaker (i.e. higher value) pull-ups will make noise issues worse.
  13. A MSP430F415 in a cheap fingertip oximeter from AliExpress Teardown here: http://www.kean.com.au/oshw/oximeter/ I wonder if that nicely labeled JTAG header is still functional. With 16K Flash and 512 bytes of RAM, this MCU is comparable to the MSP430G2553. Energia on an oximeter anyone? Addendum 2/28: I ordered an identical looking model off AliExpress. Unfortunately, it's no longer MSP430 inside :-( It's now powered by a STM32F030 ARM M0.
  14. I think the regulator is fine but can't supply enough current to the 3.3V rail. I'd check the power rail for a short circuit or low resistance to ground.
  15. Please define "not work for me". At a quick glance, it doesn't look like the libraries do something incompatible with Energia.
  16. Hi Rian, The packet handler interrupt routine will send SPI commands to the radio IC. This means that you cannot make calls to the radio from the main loop after ph_start(). If you want to test communication with the radio IC, comment out ph_start(). radio_setup() does configure all the pins. One could argue that I should also have set RADIO_SDN to low in there. Instead the first few lines of radio_configure() reset the radio by setting the SDN high for a few milliseconds and then low. If you want to put a resistor on the SDN line, I'd use a pull-up to keep the radio in reset until the MCU explicitly turns it on. Either way works though. I'd go with a smaller resistor, maybe 10K. Double check the connections with the defines in the source code. I may have shuffled things around in later revisions.
  17. The redefinition of pgm_read_byte and pgm_read_word in the library (lines 18, 19) may also cause issues.
  18. Did you cross the serial lines as documented in the pinmap? Note that version 1.4 is different from 1.5. http://energia.nu/pin-maps/guide_msp430g2launchpad/
  19. Hi Rian, Are you using CCS to develop your dAISy project? I highly recommend CCS and the original project shared on Github, at least until you get that working. Energia is very limited in its debugging capabilities and may interfere in other unexpected ways. If your code hangs inside radio_configuration(), then it's very likely that there is an issue with the wiring or pin configuration. In particular RADIO_CTS (GPIO1) is critical. The radio uses this line to signal when it's ready to receive more commands from the MCU. Also RADIO_SDN (radio shutdown) needs to be set to low to turn on the radio. A simple test is to call radio_part_info() and see if the call completes or hangs. after the call radio_buffer.part_info.part_msb and part_lsb contain the part number (e.g. 4362). If it hangs, double check wiring and pin configuration for RADIO_CTS and RADIO_SDN. If the call completes, but radio_buffer does not contain useful data, verify the SPI connections (MISO, MOSI, SCLK, CS). Edit: Corrected name of RADIO_CTS pin
  20. Does the regulator or any other component get hot? You might have a short circuit on the 3.3V rail.
  21. PS: Setting up clock systems can be quite complex, especially with the newer MCUs. Take a look into MSP430Ware which should come installed with CCS. It contains convenient functions to setup your clocks without having to worry too much about registers. Looks like this tutorial on getting started with CCS and MSP430 Launchpads uses MSP430Ware. http://processors.wiki.ti.com/index.php/Getting_Started_with_the_MSP430_LaunchPad_Workshop
  22. As mentioned above, I'd focus first on communicating with the sensor before going into interrupts and timers. You can verify the clock settings by looking up the registers in the Family User Guide of your MCU. http://www.ti.com/product/MSP430FR5739/technicaldocuments#doctype6 Looking at the intro of chapter 3.4, it looks like you may need to write a password into CSCTL0 before you can write to the other registers of the clock system. You should also learn to use the debugger in CCS. It allows to execute your program step by step and looking at register values etc. http://processors.wiki.ti.com/index.php/GSG:Debugging_projects_v5#Launching_the_debugger
  23. Another MSP430, this time it's a MSP430FR5739 running the Ring "smart" doorbell The full teardown is documented here: https://www.exploitee.rs/index.php/Ring_Doorbell I was a bit surprised to only have a "lowly" MCU in a device that streams video over WiFi. But it looks like a specialized IC by Omnivision (OV788) and the WiFi module (GainSpan GS2011M) do the grunt work. The MSP430 probably just waits for someone to press the button and then turns on LED driver, camera and WiFi. See this dev kit by the vendor of the WiFi module. http://www.gainspan.com/products/gs_adk_aek_videoov720p The wonders of integration. TI has a similar app note pairing the OV788 with a CC3200. http://www.ti.com/lit/ug/tiduck9/tiduck9.pdf
  24. @@albertRM What is your specific problem? We can't help unless you let us know which pieces of your program work and what the symptoms of your issue are. This is the thread on this forum that our ever helpful @@Rei Vilo probably is referring to: http://forum.43oh.com/topic/1825-interfacing-with-dht11-humidty-temp-sensor/ At a quick glance, I'd first try to get the sensor reading to work without involving a timer interrupt for timeouts.