Jump to content
43oh

t0mpr1c3

Members
  • Content Count

    290
  • Joined

  • Last visited

  • Days Won

    3

Reputation Activity

  1. Like
    t0mpr1c3 got a reaction from Rei Vilo in 43oh PCB Logo   
    :thumbup:
  2. Like
    t0mpr1c3 reacted to spirilis in Wireless Sensor Node with MSPG2553 and 8-pin NRF24L01+ module   
    Here's my schematic:
    DipTrace Schematic - Wireless_ADCTempSender_draft1.pdf
    OSHpark gerbers: Wireless_TempSender_nRF24.zip
     
     
    I started using the G2452 with my grill monitor, it seemed like at the time I was going to make it a solution based on a LaunchPad with the G2553 being the base station (for its UART) and the G2452 being in the external unit; shortly after I decided to use the SMD version of the G2452 instead, but my decision was made.  IMO it's a perfect chip for external nodes like this that don't need a UART; and the USI SPI implementation can do 16-bit, which I have found improves throughput (examined with the logic analyzer) to the nRF24L01+ module.  Probably not a big deal or consideration though.
    That and it's slightly cheaper than the G2553.  I ended up sampling some 14-pin TSSOP and bought like 5 of the 20-pin TSSOP versions recently.  I like both of them (G2553 and G2452).
    So in conclusion, I used the G2452 because I felt like it!
  3. Like
    t0mpr1c3 reacted to spirilis in Wireless Sensor Node with MSPG2553 and 8-pin NRF24L01+ module   
    Here's my variation of a wireless sensor node... this was inspired by a need to monitor temperatures throughout the house; I have 6 of these boards from OSHpark I just got today!
     
    http://spirilis.net/junk/msp430/tempbug.jpg
     
    Bulk of the package is the 2xAA battery pack, and I have one of my 10-pin nRF24 breakout boards with my new 10-to-8 adapter board from oshpark.  Nice & compact!
     
    Works off the G2452, I shortsightedly only offered 2 GPIO pins to mess with, P1.0 and P1.1 (the rest are used by the nRF24 or not broken out). Has pads for the PW20 version of the G2452 but since P2.0-P2.5 aren't used at all, a PW14 version works fine (got a 14-pin sample from TI on there).
     
    Has one yellow LED, 3 pins for GND/TEST/RESET for programming, and the P1.0/P1.1 pins you see at the bottom.
  4. Like
    t0mpr1c3 reacted to ike in Wireless Sensor Node with MSPG2553 and 8-pin NRF24L01+ module   
    "Can I use Schottky diodes for that purpose?" 
    Of course you can. Germanium diodes are thing from the past. There are now Schottky diodes for RF applications and Schottky diodes for power applications. 
     
    So to be useful nodes have to be cheap and you need many of them. On ebay you can buy some cheap solutions. All you need is:
    1. 10 pcs of msp430g2553 - at 8MHz you should be able to run them until you drain batteries at about 2.0V. 
    2. "10pcs nrf24l01+" about $12-$13. Those modules can run at 2.0V too.
    3. "10pcs pcb paper" about $1.58 - they are crappy http://en.wikipedia.org/wiki/FR-2 but they are cheap.
    4. "10pcs AA  battery holder" about $4.86
    And you have 10 cheap working nodes. Maybe you don't need 32khz xtal. Use VLO at 12mhz to wake up node every 2 minutes or so  to say: "I'm alive", to send collected data and then enable RX mode for about 100mS to read message queue for that node. Here is mock up of the setup:


  5. Like
    t0mpr1c3 reacted to jpnorair in Wireless Sensor Node with MSPG2553 and 8-pin NRF24L01+ module   
    Be careful with coin cells.  Coin cells usually can't source much current for very long.  If you use coin cells, you'll need to engineer the firmware more carefully to make sure to go into low power modes as often as possible, both for the MCU and the radio.
  6. Like
    t0mpr1c3 reacted to roadrunner84 in Wireless Sensor Node with MSPG2553 and 8-pin NRF24L01+ module   
    It's looking good! Quite an impressive circuit for someone new to circuit design!
     
    I had three questions/remarks:
    - Why do you use a stereo jack, while you actually use two conductors, wouldn't a mono jack be more appropriate?
    - You connect the output of your USB power converter directly to the CR2032, which will essentially try to "charge" the cell. To avoid this, you could connect a diode from the coin cell to 3V3 and a diode from U1 OUT to 3V3. This will suffer you some voltage, but when using germanium diodes, this will be only 0v3, which leaves you with 3v0 (or 2v7 from the coin cell) to use. I'm not familiar with the MIC5025, but I suspect the BP pin to be "backup power", couldn't you connect the coin cell to that pin instead?
    - TEST is left floating in most circuits, as in yours. This works most of the times. I have learned however that you'd better pull it down with a 47k resistor to ground, just in case to keep the level steady in noisy environments.
  7. Like
    t0mpr1c3 reacted to roadrunner84 in Wireless Sensor Node with MSPG2553 and 8-pin NRF24L01+ module   
    I'd prefer to use diodes on the commong Vcc, instead of the common Gnd. But you'd need a common anode type instead of a common cothode type dual diode. This will probably just work fine.
     
    If you want to go for cheap: there are two major types of coincell holders: the "real" ones, in which you clip the coin. And the "spring" version, which are basically a piece of spring steel bend to clamp a coincell between the spring and the PCB. The latter can be got at dirty cheap rates through the right places.
     
    If you want to get rid of the crystal, you might try to "sync" time over the network from one or a few nodes that do have the crystal in place. If you sync, say, avery quarter of an hour, you could get fairly accurate timing, even in nodes running from VLO.
    VLO suffers from temperature changes, but in most environments you don't have changes so rapid that you couldn't compensate within half an hour.
  8. Like
    t0mpr1c3 got a reaction from xxx1 in Wireless Sensor Node with MSPG2553 and 8-pin NRF24L01+ module   
    This is my first time designing a PCB for MSP430. I really like the NRF24L01+ booster pack but I would like something smaller to use for remote temperature sensors. With that in mind I've designed a 24.5 x 50 mm PCB (2 on a 5x5 cm prototype) featuring MSP430G2553 and an adapter for a 8-pin NRF24L01+ module using essentially the same pinout, with the intention of using the Spirilis library. There's a jack socket to connect a 1-wire sensor (e.g. DS18B20), a 4-pin header to connect a temperature/humidity sensor (SHT22 or similar), a programming header that gives serial access, and 3 other general purpose I/O pins. You could connect a thermistor or LM35 to the jack socket by leaving off the 4.7K pullup resistor on the data pin. Power can be supplied by a CR2032 coin cell or via a mini USB and LDO voltage regulator.
     
    The repository is https://github.com/t0mpr1c3/wisenode although I haven't put up any documentation yet, just the Eagle files. I'm really very new to circuit board design so please if you can see any improvements do leave a comment for me. Thanks!
  9. Like
    t0mpr1c3 got a reaction from Automate in Wireless Sensor Node with MSPG2553 and 8-pin NRF24L01+ module   
    This is my first time designing a PCB for MSP430. I really like the NRF24L01+ booster pack but I would like something smaller to use for remote temperature sensors. With that in mind I've designed a 24.5 x 50 mm PCB (2 on a 5x5 cm prototype) featuring MSP430G2553 and an adapter for a 8-pin NRF24L01+ module using essentially the same pinout, with the intention of using the Spirilis library. There's a jack socket to connect a 1-wire sensor (e.g. DS18B20), a 4-pin header to connect a temperature/humidity sensor (SHT22 or similar), a programming header that gives serial access, and 3 other general purpose I/O pins. You could connect a thermistor or LM35 to the jack socket by leaving off the 4.7K pullup resistor on the data pin. Power can be supplied by a CR2032 coin cell or via a mini USB and LDO voltage regulator.
     
    The repository is https://github.com/t0mpr1c3/wisenode although I haven't put up any documentation yet, just the Eagle files. I'm really very new to circuit board design so please if you can see any improvements do leave a comment for me. Thanks!
  10. Like
    t0mpr1c3 got a reaction from RichardVowles in Wireless Sensor Node with MSPG2553 and 8-pin NRF24L01+ module   
    This is my first time designing a PCB for MSP430. I really like the NRF24L01+ booster pack but I would like something smaller to use for remote temperature sensors. With that in mind I've designed a 24.5 x 50 mm PCB (2 on a 5x5 cm prototype) featuring MSP430G2553 and an adapter for a 8-pin NRF24L01+ module using essentially the same pinout, with the intention of using the Spirilis library. There's a jack socket to connect a 1-wire sensor (e.g. DS18B20), a 4-pin header to connect a temperature/humidity sensor (SHT22 or similar), a programming header that gives serial access, and 3 other general purpose I/O pins. You could connect a thermistor or LM35 to the jack socket by leaving off the 4.7K pullup resistor on the data pin. Power can be supplied by a CR2032 coin cell or via a mini USB and LDO voltage regulator.
     
    The repository is https://github.com/t0mpr1c3/wisenode although I haven't put up any documentation yet, just the Eagle files. I'm really very new to circuit board design so please if you can see any improvements do leave a comment for me. Thanks!
  11. Like
    t0mpr1c3 reacted to bluehash in [Group Buy-8][C]NRF24L01+ Wireless Transceiver Module - ~$2   
    Okay.. you can go ahead and order. Please remember, that these will be shipped only after the radios arrive. The radios have reached the US, but a few days more to reach me.
     
    PCB Pair order
    Radio Pair order
     
    You may add headers and other stuff from the shop. Try to order it today or tomorrow.
    Thanks!
  12. Like
    t0mpr1c3 got a reaction from bluehash in Arrow's Black November - Complimentary Shipping on Any Online Order   
    Well, to Arrow's credit a sales rep emailed me when the order went through so I had someone to contact with my complaint. He got back to me within minutes, and in response to my ventilation, came back with this:
     
     
     
    So, I didn't qualify for free shipping, but they will ship it free anyway. I have no fault with their good customer service. Thanks Conor Hickey at Arrow for sorting that out.
  13. Like
    t0mpr1c3 got a reaction from cubeberg in Arrow's Black November - Complimentary Shipping on Any Online Order   
    Well, to Arrow's credit a sales rep emailed me when the order went through so I had someone to contact with my complaint. He got back to me within minutes, and in response to my ventilation, came back with this:
     
     
     
    So, I didn't qualify for free shipping, but they will ship it free anyway. I have no fault with their good customer service. Thanks Conor Hickey at Arrow for sorting that out.
  14. Like
    t0mpr1c3 got a reaction from x220 in Glue recommendation   
    Hot glue is not just quick, it is also flexible and won't rattle loose. Great for strain relief and fabrics.
     
    Epoxy is the fallback, strong and sticks to almost anything, but inflexible. Goopy contact adhesives can be preferable where some flexibility is required.
     
     
    Silicone is flexible, waterproof, food safe, heat resistant.
     
     
    Super glue is brittle, not that strong, and needs to be kept in the fridge. I usually only use it where I need something quick that flows into small gaps.
     
    Wood glue for, uh, I forget.
     
    Mixtures of glues can be useful e.g. contact adhesive to hold items in place while epoxy cures.
  15. Like
    t0mpr1c3 got a reaction from GeekDoc in Glue recommendation   
    Hot glue is not just quick, it is also flexible and won't rattle loose. Great for strain relief and fabrics.
     
    Epoxy is the fallback, strong and sticks to almost anything, but inflexible. Goopy contact adhesives can be preferable where some flexibility is required.
     
     
    Silicone is flexible, waterproof, food safe, heat resistant.
     
     
    Super glue is brittle, not that strong, and needs to be kept in the fridge. I usually only use it where I need something quick that flows into small gaps.
     
    Wood glue for, uh, I forget.
     
    Mixtures of glues can be useful e.g. contact adhesive to hold items in place while epoxy cures.
  16. Like
    t0mpr1c3 reacted to spirilis in Charcoal Grill / Smoker Monitor   
    Ok so this is my inaugural MSP430 project, i.e. the first legitimately useful thing I've built since buying a LaunchPad.
     
    One of my bosses at work asked me, after I babbled on about my Arduino work et al, "So what would it take for me to get text messages when my Big Green Egg is done cooking my pork shoulder roast?"
     
    As it turns out, there are commercial solutions out there which will not only monitor your grill & roast temperatures--but also CONTROL them through some sort of fan mounted on a custom fan shroud that replaces the air inlet draft door. These solutions all cost $300+, usually $400-600 for the automated control ones, so I figured there's room for improvement on the price point and DIY'ability of this.
    These solutions also seem to require AC power (or AC adapter) of some sort, and I didn't look to see if there was much weatherproofing of that.
     
    So I devised a couple requirements of my own:
    1. This solution must be an appliance, permanently installed and able to withstand the elements. Maryland doesn't get anything too extreme, maybe 5F (-15C) temps in the depths of winter and upwards of 105F (40C) temps at the peak of summer. Variable rain, snow, ice. I maintain this requirement because I hate dragging gadgets out to plug in/set up when I already have a zillion small tasks in my head.
    2. This solution needs to come in at under $200 for everything.
    3. There should be an expansion capability built in for adding other stuff--like the ability to control a draft fan, or the ability to show the grill + meat temperatures on some sort of portable display (besides a cellphone)
    4. There needs to be Internet capability, even if it's through a stationary PC or Mac that talks to a base station MSP430.
     
    What I came up with was a solution based on the MSP430 Value Line chips, Nordic Semiconductor nRF24L01+ transceivers and Maxim MAX31855 digital thermocouple readers. A base station composed of a LaunchPad board with Nordic nRF24L01+ boosterpack (bonus also includes FTDI 6-pin pinout for high speed serial) comprises the internal half of the solution, and software running on a PC/Mac (currently a Linux server) does the dirty Internet work.
     
    THERMOCOUPLE SENDER UNIT
    The exterior unit that is hardened to the elements/etc. is a custom PCB (OSHpark.com) with an MSP430G2452 TSSOP chip, two MAX31855's, two screw terminals, a Nordic nRF24L01+ board bought off eBay for $2 and some power regulation hardware to take two AA batteries and generate a fairly clean 3.3V rail (required by the MAX31855's, it can't go down to 1.8-2.0V like the MSP430 and nRF24 can...).
    The board was designed to fit inside an enclosure sold by Polycase -- the WC-22F (http://www.polycase.com/wc-22f) -- with a cable gland installed in the side to feed the thermocouple leads while maintaining the watertightness of the enclosure.
     
    Pic of the external unit installed:

     
    The bottom side of the PCB with the MSP430:

     
    Schematic - DipTrace_Schematic_-_GrillMonitor_draft6.pdf
    Gerber files (OSHpark ready to use) - GrillMon_ExtSenderUnit_43oh.zip
     
    Thermocouples I ended up using - http://www.auberins....e5b2d83c4c4407a
     
     
     
    GRILL MONITOR BASE STATION
    The main requirements for the base station is some way to talk to a PC and some way to receive the RF information from the external sending unit. A $4.30 LaunchPad board works fine for this with a custom boosterpack to attach a nRF24L01+ breakout board. I tossed in an FTDI pinout just in case I was having trouble with the LaunchPad's application UART, which ended up being the case (the Linux driver I found for cdc-acm kernel panics my server after a day or 2 of use).
     
    Pic of the LP + boosterpack (note- I used an nRF24L01+ module with an RP-SMA antenna, it cost around $12 vs the $2 for the PCB trace version).

     
    Schematic of the BoosterPack - DipTrace_Schematic_-_GrillMonitor_BaseStn_draft4.pdf
    Gerber files (OSHpark ready to use) - GrillMon_BaseStation_43oh.zip
     
     
     
    CODE
     
    I went ahead and took a current snapshot of my work (I am using git, but, don't have it up on github yet) and here it is:
    http://spirilis.net/...urce-0.1.tar.gz
     
    Note this includes 2 libraries I wrote, "msprf24" -- http://github.com/spirilis/msprf24 and mspuartcli -- http://github.com/spirilis/mspuartcli
    The latter library I wrote in a hurry, debugged it a bit here and there, but frankly it could use some improvement (e.g. toss the print functions and just use oPossum's printf() implementation). It does work however!
     
    I'll go ahead and include some of the main code for the external sensor unit:
     
    tcsender.h -- header info for tcsender main prog

    /* tcsender.h * * Main program - exported global variables and #define constants */ #ifndef TCSENDER_H #define TCSENDER_H /* Sleep interval between thermocouple reads; in units of 46ms */ // Set to 2 minutes (2608*46ms) #define SLEEP_INTERVAL_BETWEEN_TC_READS 2608 /* RX window after a thermocouple read; a back-window to receive GPIO updates from the base station */ // Set to ~322ms (7*46ms) #define SLEEP_INTERVAL_RX_BACKWINDOW 7 // Interval between LED test polls #define SLEEP_INTERVAL_TEST_POLLS 4 // Number of attempts to send packet (multiply this times 30ms each, which constitutes 15 retries each) #define RETRY_ATTEMPTS 32 // nRF24L01+ RF channel & speed #define RF_CHANNEL 10 #define RF_SPEED RF24_SPEED_MIN // Protocol device IDs (not RFaddr, used to uniquely identify different thermocouple devices) #define DEVICE_ID 0x01 #define DEVICE_ID_TC1 0x01 #define DEVICE_ID_TC2 0x02 // Test LEDs #define LED_RED_PORTOUT P2OUT #define LED_RED_PORT BIT6 #define LED_GREEN_PORTOUT P2OUT #define LED_GREEN_PORT BIT7 // Thermocouple control & SPI #define TC_MOSFET_PORTOUT P2OUT #define TC_MOSFET_PORT BIT0 #define TC1_CS_PORTOUT P1OUT #define TC1_CS_PORT BIT3 #define TC2_CS_PORTOUT P1OUT #define TC2_CS_PORT BIT4 // External GPIO ports #define GPIO_1_PORTOUT P2OUT #define GPIO_1_PORT BIT1 #define GPIO_2_PORTOUT P2OUT #define GPIO_2_PORT BIT3 #define EXTSPI_CS1_PORTOUT P2OUT #define EXTSPI_CS1_PORT BIT2 #define EXTSPI_CS2_PORTOUT P2OUT #define EXTSPI_CS2_PORT BIT4 // Test mode jumper input pin #define TEST_MODE_PORTIN P2IN #define TEST_MODE_PORT BIT5 #endif
     
    TCsender main() function -- main.c:

    /* TCsender * * Grill Monitor/Remote Thermocouple Sensor Unit * Main code * * Provides data from 2 thermocouples over an nRF24L01+ transceiver to * a Base Station which should be listening. Base Station is also * relied upon for RF test data, and in TEST mode this unit will frequently * request Test LED information from the base to reflect on this unit's red LED. * * Designed for the Texas Instruments MSP430 G2452 Value Line microcontroller * with a Nordic Semiconductor nRF24L01+ attached to the USI port. * * Thermocouple data is accessed via a pair of Maxim MAX31855K digital thermocouple * amplifiers accessed over the same USI SPI port; power to the MAX31855's are enabled * or disabled using a MOSFET controlled by one of the MSP430's pins. * * Utilizes VLOCLK as a timer for scheduling thermocouple-read events and Test LED * packet requests during TEST mode. */ #include <msp430.h> #include "tcsender.h" #include "packet_processor.h" #include "nrf_userconfig.h" #include "msprf24.h" #include <sys/cdefs.h> #include <string.h> const char tcsender_rxaddr[] = {0xDE, 0xAD, 0xBE, 0xEF, 0x02}; const char tcsender_dummyaddr[] = {0x00, 0x00, 0x00, 0x00, 0x00}; const char basestation_rxaddr[] = {0xDE, 0xAD, 0xBE, 0xEF, 0x01}; volatile unsigned int sleep_counter, rx_waitack; unsigned int tcread_count, txfail_count; char rfbuf[32]; // Sharing this with test_mode_main // Function prototypes void test_mode_main(); void thermocouple_wakeup(); void thermocouple_sleep(); char thermocouple_read(char tcid, struct packet_task *taskbuf); void debug_packet(struct packet_task *taskbuf); void wdt_suspend(); void wdt_unsuspend(); // Main program int main() { char task_rxwindow_after_txack, txretry_count, txretry_latch; char do_lpm; int i; char pipeid, pktlen; WDTCTL = WDTPW | WDTHOLD; DCOCTL = CALDCO_16MHZ; BCSCTL1 = CALBC1_16MHZ; BCSCTL2 = DIVS_2; // SMCLK = DCOCLK/4, or 4MHz /* nRF24L01+ supports up to 10MHz, but the MAX31855 * only supports 5MHz SPI. */ BCSCTL3 = LFXT1S_2; // ACLK = VLOCLK while (BCSCTL3 & LFXT1OF) ; // Wait until the VLOCLK is up, running & stable /* Initialize/reset all I/O ports */ P1DIR = 0x00; P1OUT = 0x00; P1SEL = 0x00; P1SEL2 = 0x00; P1REN = 0x00; P1IFG = 0x00; P1IE = 0x00; P2DIR = 0x00; P2OUT = 0x00; P2SEL = 0x00; P2SEL2 = 0x00; P2REN = 0x00; P2IFG = 0x00; P2IE = 0x00; /* Init I/O ports for application use */ // Test LEDs P2DIR |= LED_RED_PORT | LED_GREEN_PORT; // Thermocouple Vcc MOSFET & SPI CS lines--turn on initially so nRF24 init can occur P2DIR |= TC_MOSFET_PORT; TC_MOSFET_PORTOUT &= ~TC_MOSFET_PORT; // LOW=on P1DIR |= TC1_CS_PORT | TC2_CS_PORT; TC1_CS_PORTOUT |= TC1_CS_PORT; TC2_CS_PORTOUT |= TC2_CS_PORT; // External GPIO & SPI CS ports P2DIR |= GPIO_1_PORT | GPIO_2_PORT | EXTSPI_CS1_PORT | EXTSPI_CS2_PORT; // Test mode jumper input pin P2OUT |= TEST_MODE_PORT; // Pull-up enabled P2REN |= TEST_MODE_PORT; P2IES |= TEST_MODE_PORT; // Interrupt on falling-edge P2IE |= TEST_MODE_PORT; // nRF24L01+ configuration & initialization rf_crc = RF24_EN_CRC | RF24_CRCO; // CRC enabled, 16-bit rf_addr_width = 5; rf_speed_power = RF_SPEED | RF24_POWER_MAX; // RF_SPEED from tcsender.h rf_channel = RF_CHANNEL; // This #define is located in tcsender.h msprf24_init(); msprf24_open_pipe(0, 1); // Open pipe#0 with Enhanced ShockBurst for receiving Auto-ACKs msprf24_open_pipe(1, 1); // Pipe#1 is the primary receiver for base->slave traffic msprf24_set_pipe_packetsize(0, 0); // Dynamic packet sizes msprf24_set_pipe_packetsize(1, 0); // Dynamic packet sizes w_rx_addr(0, (char*)tcsender_dummyaddr); w_rx_addr(1, (char*)tcsender_rxaddr); // For receiving base->slave packets // Now that the nRF24 module has been initialized, we can shut off the TC amps. thermocouple_sleep(); // Set up WDT interval timer as a scheduler sleep_counter = 0; WDTCTL = WDT_ADLY_16; // 46ms per overflow with VLOCLK IFG1 &= ~WDTIFG; IE1 |= WDTIE; // Main loop task_rxwindow_after_txack = 0; rx_waitack = 0; txretry_count = 0; txretry_latch = 0; tcread_count = 0; txfail_count = 0; while (1) { do_lpm = 1; // Handle RF acknowledgements & RX packets if (rf_irq & RF24_IRQ_FLAGGED) { msprf24_get_irq_reason(); // Handle TX acknowledgements if (rf_irq & RF24_IRQ_TX) { // Acknowledge msprf24_irq_clear(RF24_IRQ_TX); flush_tx(); // Load dummy address into pipe#0 w_rx_addr(0, (char*)tcsender_dummyaddr); // Shut off green LED to indicate we're finished LED_GREEN_PORTOUT &= ~LED_GREEN_PORT; txretry_count = 0; // Reset this txretry_latch = 0; } if (rf_irq & RF24_IRQ_TXFAILED) { // Acknowledge msprf24_irq_clear(RF24_IRQ_TXFAILED); // If we have not exhausted our txretry_count's, resubmit the packet. if (txretry_count) { txretry_count--; if (!txretry_latch) { txretry_latch = 1; tx_reuse_lastpayload(); } pulse_ce(); } else { flush_tx(); w_rx_addr(0, (char*)tcsender_dummyaddr); LED_GREEN_PORTOUT &= ~LED_GREEN_PORT; txretry_latch = 0; } txfail_count++; } // Handle RX packets if (rf_irq & RF24_IRQ_RX) { pktlen = r_rx_peek_payload_size(); pipeid = r_rx_payload(pktlen, rfbuf); msprf24_irq_clear(RF24_IRQ_RX); /* Ignore any 0-byte receives, and we only care * about packets coming for pipe#1 */ if (pktlen && pipeid == 1) { for (i=0; i<pktlen; i++) { if (rfbuf[i]) { // Only process this packet if the length does not send us past the buffer! // (otherwise this would make an easy buffer overflow attack vector) if ((i + (unsigned char)rfbuf[i+1] + 1) < pktlen) { packet_processor((unsigned char)rfbuf[i], (unsigned char)rfbuf[i+1], &rfbuf[i+2]); i += (unsigned char)rfbuf[i+1] + 1; } } } } rx_waitack = 1; } /* If a TX acknowledgement occurred and we just sent thermocouple data, enable * a short RX backwindow */ if (task_rxwindow_after_txack && (rf_irq & (RF24_IRQ_TX|RF24_IRQ_TXFAILED)) && !txretry_count) { sleep_counter = SLEEP_INTERVAL_RX_BACKWINDOW; msprf24_activate_rx(); // Switch on green LED to indicate we're actively using RF LED_GREEN_PORTOUT |= LED_GREEN_PORT; } do_lpm = 0; // Prefer to always loop once more after handling nRF24 events } // Check for TEST mode (active=LOW) if ( !(TEST_MODE_PORTIN & TEST_MODE_PORT) ) { // Mandatory 92ms debounce period int old_sleep_counter = sleep_counter - 2; sleep_counter = 2; while(sleep_counter) LPM3; if ( !(TEST_MODE_PORTIN & TEST_MODE_PORT) ) { flush_tx(); flush_rx(); thermocouple_wakeup(); test_mode_main(); sleep_counter = 0; // Force an immediate thermocouple read upon leaving Test Mode } else { if (old_sleep_counter > 0) /* Restore deep-sleep counter in case the TEST line gets flappy so we don't * waste too much power with this crap */ sleep_counter = old_sleep_counter; } } // Did we just finish a long sleep-between-TC-read? if (!sleep_counter) { // Is this the end of the RX-backwindow-after-TX? if (task_rxwindow_after_txack) { msprf24_powerdown(); flush_tx(); flush_rx(); msprf24_irq_clear(RF24_IRQ_MASK); LED_GREEN_PORTOUT &= ~LED_GREEN_PORT; // Shut off green LED to indicate we're not listening anymore thermocouple_sleep(); /* This is the safest time to shut off the TC amplifiers, since we're * done all SPI I/O now. */ task_rxwindow_after_txack = 0; sleep_counter = SLEEP_INTERVAL_BETWEEN_TC_READS; } else { // Wake everyone up and perform a TC read! thermocouple_wakeup(); msprf24_standby(); tcread_count++; // Perform TC read, append TX packet tasks struct packet_task tcpkt; if (thermocouple_read(DEVICE_ID_TC1, &tcpkt)) packet_task_append(&tcpkt); if (thermocouple_read(DEVICE_ID_TC2, &tcpkt)) packet_task_append(&tcpkt); debug_packet(&tcpkt); packet_task_append(&tcpkt); // TC packet will be sent shortly after this with packet_process_txqueue() /* Flag the nRF24 IRQ handler that we should enable a 322ms RX window * once this transmission has acknowledged. */ task_rxwindow_after_txack = 1; // Attempt to retransmit for at least 1/2 second before giving up txretry_count = RETRY_ATTEMPTS; } } if (packet_task_next() != NULL) { if (!rx_waitack) { if (packet_process_txqueue()) // Switch on Green LED to indicate we have a transmission in progress LED_GREEN_PORTOUT |= LED_GREEN_PORT; } } if (do_lpm) { LPM3; } } return 0; // This should cause a reset, but it should never be reached. } volatile unsigned int tx_count; void test_mode_main() { char do_lpm; int i; struct packet_task txpkt, *pt; char pipeid, pktlen; LED_RED_PORTOUT &= ~LED_RED_PORT; LED_GREEN_PORTOUT &= ~LED_GREEN_PORT; tx_count = 0; sleep_counter = 0; // Alternative main loop for when the TEST jumper is active. (active=LOW) while ( !(TEST_MODE_PORTIN & TEST_MODE_PORT) ) { do_lpm = 1; if (rf_irq & RF24_IRQ_FLAGGED) { msprf24_get_irq_reason(); if (rf_irq & (RF24_IRQ_TX|RF24_IRQ_TXFAILED)) { msprf24_irq_clear(RF24_IRQ_TX|RF24_IRQ_TXFAILED); flush_tx(); w_rx_addr(0, (char*)tcsender_dummyaddr); msprf24_activate_rx(); LED_GREEN_PORTOUT &= ~LED_GREEN_PORT; tx_count++; // just used for debugging } if (rf_irq & RF24_IRQ_RX) { // Read packet & process pktlen = r_rx_peek_payload_size(); pipeid = r_rx_payload(pktlen, rfbuf); msprf24_irq_clear(RF24_IRQ_RX); /* Ignore any 0-byte receives, and we only care * about packets coming for pipe#1 */ i = 0; if (pktlen && pipeid == 1) { for (i=0; i<pktlen; i++) { if (rfbuf[i]) { // Only process this packet if the length does not send us past the buffer! // (otherwise this would make an easy buffer overflow attack vector) if ((i + (unsigned char)rfbuf[i+1] + 1) < pktlen) { packet_processor((unsigned char)rfbuf[i], (unsigned char)rfbuf[i+1], &rfbuf[i+2]); i += (unsigned char)rfbuf[i+1] + 1; } } } } } do_lpm = 0; } if (!sleep_counter) { // Send Test LED Request packet txpkt.program = 0x02; txpkt.size = 6; memcpy(&(txpkt.rfaddr[0]), basestation_rxaddr, 5); txpkt.data[0] = DEVICE_ID; memcpy(&(txpkt.data[1]), tcsender_rxaddr, 5); packet_task_append(&txpkt); sleep_counter = SLEEP_INTERVAL_TEST_POLLS; } if (!(rf_irq & RF24_IRQ_FLAGGED) && (pt = packet_task_next()) != NULL) { if (packet_process_txqueue()) LED_GREEN_PORTOUT |= LED_GREEN_PORT; } if (do_lpm) LPM3; } msprf24_standby(); // Leave the calling function in a powered-on standby state msprf24_irq_clear(RF24_IRQ_MASK); // Clear any outstanding TX packets, queues or IRQs flush_tx(); flush_rx(); packet_init_tasklist(); LED_RED_PORTOUT &= ~LED_RED_PORT; LED_GREEN_PORTOUT &= ~LED_GREEN_PORT; } void thermocouple_wakeup() { // Activate Thermocouple Amplifiers TC_MOSFET_PORTOUT &= ~TC_MOSFET_PORT; TC1_CS_PORTOUT |= TC1_CS_PORT; TC2_CS_PORTOUT |= TC2_CS_PORT; // Wait over 200ms for the first valid results to come in (BLOCKING SLEEP) sleep_counter = 6; while (sleep_counter) LPM3; } void thermocouple_sleep() { // Deactivate thermocouple amplifiers TC_MOSFET_PORTOUT |= TC_MOSFET_PORT; // Shut off SPI CS lines to avoid parasitic power TC1_CS_PORTOUT &= ~TC1_CS_PORT; TC2_CS_PORTOUT &= ~TC2_CS_PORT; /* Note that the SPI SCLK pin will still provide some parasitic power so long as we're * doing SPI communication. Cleanest way to resolve this is to avoid calling this function * until we're done all SPI I/O and are ready to go into deep sleep for a while. */ } char thermocouple_read(char tcid, struct packet_task *taskbuf) { unsigned int tcread[2]; int temp; unsigned char portbit; switch (tcid) { case DEVICE_ID_TC1: portbit = TC1_CS_PORT; break; case DEVICE_ID_TC2: portbit = TC2_CS_PORT; break; default: return 0; } taskbuf->program = 0x10; taskbuf->size = 6; taskbuf->data[0] = tcid; memcpy(&taskbuf->rfaddr[0], basestation_rxaddr, 5); // SPI I/O TC1_CS_PORTOUT &= ~portbit; tcread[0] = spi_transfer16(0xFFFF); tcread[1] = spi_transfer16(0xFFFF); TC1_CS_PORTOUT |= portbit; // Interpret numbers into degrees C for TC temp temp = (int) ((tcread[0] & 0xFFF0) >> 4); if (temp & 0x0800) temp |= 0xF000; // Properly sign-extend negative values memcpy(&(taskbuf->data[1]), &temp, sizeof(int)); // Interpret numbers into degrees C for Ambient temp temp = (int) ((tcread[1] & 0xFF00) >> 8); if (temp & 0x0080) temp |= 0xFF00; // Properly sign-extend negative values memcpy(&(taskbuf->data[3]), &temp, sizeof(int)); // Interpret fault codes taskbuf->data[5] = 0; if (tcread[1] & 0x0001) // Open circuit taskbuf->data[5] = 1; if (tcread[1] & 0x0002) // Short to GND taskbuf->data[5] = 3; if (tcread[1] & 0x0004) // Short to +Vcc taskbuf->data[5] = 2; return 1; } void debug_packet(struct packet_task *taskbuf) { unsigned char *devidptr = (unsigned char *) &(taskbuf->data[0]); /* making sure the (unsigned) DEVID isn't clobbered by the * signed char nature of the data[] array */ *devidptr = DEVICE_ID; memcpy(&(taskbuf->data[1]), &tcread_count, 2); // # times we've woken up to read/xmit the thermocouple data memcpy(&(taskbuf->data[3]), &txfail_count, 2); // # times we've seen a TXFAILED IRQ memcpy(&(taskbuf->data[5]), &devidptr, 2); // Stack address of the devidptr variable created here, to watch/detect memory leaks taskbuf->program = 0xFE; taskbuf->size = 7; memcpy(&taskbuf->rfaddr[0], basestation_rxaddr, 5); } void wdt_suspend() { IE1 &= ~WDTIE; } void wdt_unsuspend() { IE1 |= WDTIE; } // WDT overflow/timer #pragma vector=WDT_VECTOR __interrupt void WDT_ISR(void) { IFG1 &= ~WDTIFG; if (rx_waitack) { rx_waitack--; if (!rx_waitack) __bic_SR_register_on_exit(LPM3_bits); } if (sleep_counter) sleep_counter--; else __bic_SR_register_on_exit(LPM3_bits); } // PORT2 interrupt ISR // Note that our nRF24L01+ IRQ is attached to PORT1, so the msprf24 library is not providing // this ISR, thus we should provide our own. #pragma vector=PORT2_VECTOR __interrupt void P2_ISR(void) { if (P2IFG & TEST_MODE_PORT) { P2IFG &= ~TEST_MODE_PORT; __bic_SR_register_on_exit(LPM3_bits); } }
     
    One interesting thing to note here is how I handled the MAX31855's power consumption during idle--there's a small signal FET gating Vcc on both chips controlled by one of the G2452's I/O pins, however turning off Vcc doesn't solve the problem since it can grab parasitic current from the SPI lines as well as the Chip Select lines. So I have to make sure that any time the chip is in a state where SPI I/O may occur, the thermocouple chips are up and running, and only right before I go into extended low-power LPM3 sleep should I shut off the Vcc (and SPI CS lines for the chips).
     
     
    As for the OTA binary protocol, I came up with my own little scheme which is detailed in the code tarball under PROTOCOL.txt. From the G2452 side though, here's the code that interprets/processes incoming packets:
     
    packet_processor.h

    /* packet_processor.h * * Handle slave node packets (TX or RX) * * Headers & reference documentation * Struct for managing packet task list */ /* Command/packet reference: * +---------+-----------+----------------+ * | PROGRAM | PACKETLEN | PACKETCONTENTS | * +---------+-----------+----------------+ * * Programs: * 0x01 : Hello (slave->base) * 0x02 : LEDtest request (slave->base) * 0x03 : LEDtest reply (base->slave) * 0x04 : GPIO set (base->slave) * 0x05 : GPIO get request (base->slave) * 0x06 : GPIO get reply (slave->base) * 0x10 : Thermocouple status (slave->base) */ #define PACKET_TASKLIST_DEPTH 3 // Packet TX task; a single-linked list struct packet_task { unsigned char active; unsigned char program; unsigned char size; char rfaddr[5]; char data[16]; }; extern struct packet_task txtasks[PACKET_TASKLIST_DEPTH]; // Task list void packet_init_tasklist(); char packet_task_append(struct packet_task *task); struct packet_task *packet_task_next(); char packet_processor(unsigned char program, unsigned char size, char *data); // Processes an RX packet, one at a time, returning 1 if successful char packet_process_txqueue(); /* Submits a TX packet stuffing as many packets with the same RF address as can fit * inside a 32-byte packet; returns 1 if successful or 0 if no packets found in the task * queue. * This function runs msprf24_activate_tx() and the MCU should enter LPM sleep shortly after * successful completion of this function, handling IRQ upon wakeup. After waking up it's * prudent to clear RX pipe#0's address (w_rx_addr(0, <some_dummy_array_of_zeroes>)) to avoid * inadvertently capturing other traffic destined to that remote module if we enter RX mode later. */
     
    packet_processor.c

    /* packet_processor.c * Handle slave node packets (TX or RX) */ #include <msp430.h> #include "tcsender.h" #include "packet_processor.h" #include "msprf24.h" #include <sys/cdefs.h> #include <string.h> #include <stdlib.h> struct packet_task txtasks[PACKET_TASKLIST_DEPTH]; char packet_task_append(struct packet_task *task) { int i=0; if (task == NULL) return 0; // Invalid request while (txtasks[i].active && i < PACKET_TASKLIST_DEPTH) i++; if (i == PACKET_TASKLIST_DEPTH) return 0; // No free slots in the tasklist queue memcpy(&(txtasks[i]), task, sizeof(struct packet_task)); txtasks[i].active = 1; return 1; } struct packet_task *packet_task_next() { int i; for (i=0; i < PACKET_TASKLIST_DEPTH; i++) { if (txtasks[i].active) return &txtasks[i]; } return NULL; } void packet_init_tasklist() { int i; for (i=0; i < PACKET_TASKLIST_DEPTH; i++) { txtasks[i].active = 0; txtasks[i].program = 0; txtasks[i].size = 0; } } /* Process RX packet payloads * * Some commands may result in TX replies, which are appended to the * packet task list. */ char packet_processor(unsigned char program, unsigned char size, char *data) { unsigned char *udata = (unsigned char*)data; switch (program) { case 0x03: // LED test reply // Data: ID(1), LED_EN(1) if (size != 2) return 0; // Packet length invalid if (udata[0] != DEVICE_ID) return 0; // Packet was sent to the wrong device if (udata[1]) LED_RED_PORTOUT |= LED_RED_PORT; else LED_RED_PORTOUT &= ~LED_RED_PORT; return 1; default: return 0; } return 1; } /* Process all outstanding TX packet payloads of a similar RF address */ char packet_process_txqueue() { char packet[32], *curaddr; int plen=0; struct packet_task *ct; // No point in sending a packet until the TX queue is empty if ( msprf24_queue_state() & RF24_QUEUE_TXFULL ) return 0; if ((ct = packet_task_next()) == NULL) return 0; curaddr = ct->rfaddr; do { if (ct->active && !memcmp(ct->rfaddr, curaddr, 5)) { if ( (ct->size + 2 + plen) < 32 ) { packet[plen++] = ct->program; packet[plen++] = ct->size; memcpy(&packet[plen], ct->data, ct->size); plen += ct->size; ct->active = 0; // Delete task; it's handled } if (ct->size > 16) // Cull any invalid/faulty-sized packets ct->active = 0; } ct = packet_task_next(); } while (ct != NULL); if (!plen) return 0; w_tx_addr(curaddr); w_rx_addr(0, curaddr); w_tx_payload(plen, packet); // Let'er rip msprf24_activate_tx(); return 1; }
     
    That is all for now (no idea if this post is exceeding any limits for that matter...) but I'll post more details as questions come!
  17. Like
    t0mpr1c3 got a reaction from spirilis in Charcoal Grill / Smoker Monitor   
    Looks tasty! I like your design choices.
     
    I had fun making a PID controlled flowerpot smoker this summer.
  18. Like
    t0mpr1c3 got a reaction from simpleavr in List of MSP430 Webpages and Blogs   
    This is a must: http://www.simpleavr.com/
     
    I only have one 430 project on myblog so far. I plan more for the future plus Stellaris stuff : http://smokedprojects.blogspot.com
     
    Edit: also http://dangerousprototypes.com/category/msp430/
  19. Like
    t0mpr1c3 reacted to oPossum in LogicBoost, Launchpad Mini, 3 way proto PCBs for sale   
    I have a limited quantity of 3 of my PCB designs for sale. These where made to validate the design and there are few minor cosmetic problems...
    LogicBoost: Used proportional font by mistake, so text was too large and ran in to stuff. (see pics)
    3 way proto: Use proportional font when adding order # - ran in to LED text (see pics). Solder pads do not have stop attribute set, so not as much tin around the hole as there should be.
    LaunchPad Mini: No problems noticed.
     
    I don't normally sell anything due to a lack of time. This is a 'one time deal'. If you like a PCB I have designed, you will usually have to get it made yourself or convince blu# to have some made for the store.
     
    Price is $12 for a set of three boards.
    Free shipping to USA. PM me with your address for shipping cost outside of USA.
    Send paypal for what you want to pcb2012 (at) compendiumarcana (dot) com. I will update this thread when no more are available.
     
    LogicBoost 6 channel logic analyzer
    LaunchPad Mini rev 3
    3 way proto board
  20. Like
    t0mpr1c3 reacted to bluehash in Quacking oven timer   
    One more post and you will be able to post links.
    Here is the HaD link btw. Congratulations!
    http://hackaday.com/2012/09/26/quacking-egg-timer/
  21. Like
    t0mpr1c3 got a reaction from dacoffey in Quacking oven timer   
    I mashed together a MSP430G2231, a 4 digit LED display, and a quacking blinking toy duck to make an oven timer. Not quite one of a kind - the duck was from a pair of kids slippers, so I made 2 of them to give away as presents. The code is based on SimpleAVR's 3p4w clock. Enjoy.
     
    Please can a mod edit this post to correct the youtube link?
    l
    If possible I would like to link to my blog post http://smokedprojects.blogspot.com/2012 ... timer.html
     
    and the github repository of the code https://github.com/t0mpr1c3/CountdownTimer
     
    Thanks!


  22. Like
    t0mpr1c3 got a reaction from larsie in Quacking oven timer   
    I mashed together a MSP430G2231, a 4 digit LED display, and a quacking blinking toy duck to make an oven timer. Not quite one of a kind - the duck was from a pair of kids slippers, so I made 2 of them to give away as presents. The code is based on SimpleAVR's 3p4w clock. Enjoy.
     
    Please can a mod edit this post to correct the youtube link?
    l
    If possible I would like to link to my blog post http://smokedprojects.blogspot.com/2012 ... timer.html
     
    and the github repository of the code https://github.com/t0mpr1c3/CountdownTimer
     
    Thanks!


  23. Like
    t0mpr1c3 got a reaction from Nytblade in Quacking oven timer   
    I mashed together a MSP430G2231, a 4 digit LED display, and a quacking blinking toy duck to make an oven timer. Not quite one of a kind - the duck was from a pair of kids slippers, so I made 2 of them to give away as presents. The code is based on SimpleAVR's 3p4w clock. Enjoy.
     
    Please can a mod edit this post to correct the youtube link?
    l
    If possible I would like to link to my blog post http://smokedprojects.blogspot.com/2012 ... timer.html
     
    and the github repository of the code https://github.com/t0mpr1c3/CountdownTimer
     
    Thanks!


  24. Like
    t0mpr1c3 reacted to simpleavr in webbotlib speech synthesizer on launchpad   
    not sure this is considered a project. the package i am providing allows one to play w/ TTS on a launchpad w/ g2553 chip.
    i did not create the TTS s/w, credit belongs to webbot at http://webbot.org.uk
    instead of publishing derived code, i am publishing a perl script to convert his code for msp430 use.
    this allows me to avoid licensing issues and i think anyone want to implement this should look at the original source.
     
    the speech system is not high quality but fun to use in projects. i.e. talking clocks, alert / alarm modules, robot voices, etc.
     
     
    . s/w only speech synthesizer technique from webbot
    . one pin pwm.
    . text-to-speech and synthesizer code under 10k.
    . fits in a g2553 mcu.
     
    source
     
    https://github.com/simpleavr/webbot_talk430
    . hosted in github, search for "webbot_talk430" project
    . there are 4 files.
    . zconv.pl converts the webbotlib speech source codes to a msp430 compatible source.
    . talk.c TTS exercising firmware, talks to PC at 9600bps turns what u type into speech.
    . uart.h uart code
    . common.h some macros i used.
    . pwm hardware hook-up is in talk.c, just one resistor and one capacitor, can be improved by using better filters.
     


     
    instructions (as in README and help from conversion script)
     
    this is a perl script to convert the webbotlib speech sythesizer code from avr
    to msp430 usage. this script is use at your own risk giftware. webbotlib has
    it's own license terms.
     
    . locate "webbotlib" and download version 1.x, i tried w/ webbotavrclib-1.35
    . inside the package locate and extract the Audio/Text2Speech directory
    . u will see the following files
     
    Text2Speech.h
    phoneme2sound.c
    phonemeWriter.c
    sound2noise.c
    speech2phoneme.c
    speechWriter.c
    vocab_en.c
     
    . place these files in a same directory as this (zconv.pl) script
    . run it again and this script will
    . extract what's needed, ignore others
    . combine into a tighter package name "../webbot_speech.h"
    . replace avr controls w/ msp430 controls
    . to use it in your firmware, do
    . include "webbot_speech.h"
    . say("Hello World");
    . enjoy and thanks webbot
     
    <<< IMPORTANT >>>
    please observe the fact that webbotlib is GPL licensed and use / share accordingly
     
     
     
    will be glad to answer questions anyone may have in this thread. happy hacking.
×
×
  • Create New...