Jump to content

SirPatrick

Members
  • Content Count

    55
  • Joined

  • Last visited

  • Days Won

    2

Reputation Activity

  1. Like
    SirPatrick reacted to spirilis in nRF24 Temperature Sensor Bug   
    I think I mentioned this in another thread (can't find it atm) that I had built a tiny board for tossing little temperature sensor bugs everywhere, and @@yyrkoon mentioned on IRC yesterday he'd like to see the details.
     
    Of course by "bug" I mean a tiny board embedded in hidden places, not "software bug"
     
    The theme of this board is "minimalistic" design.  It's based on the MSP430G2452 since I happened to have a bunch of TSSOP's in my bin.  It includes a TSSOP-20 footprint with only a handful of pins used so a G2452 TSSOP-14 or -20 could be employed.
     
    Unfortunately I forgot to take pics last night when I hooked it all up & calibrated it
    Pics:


     
    The board breaks out P1.0 and P1.1 to some pin headers and there's GND in the SBW header set.  One thing I'd like to explore is doing a soil moisture level sensor for my wife's planters, this should work as I could supply +Vcc with P1.0 and ADC reading with P1.1 on a small board that plugs on top for the voltage divider.  With +Vcc assigned to an I/O pin the MSP430 can shut off the voltage divider for ultra-low-power sleeping.
     
    Power is supplied by 2xAA batteries, pinout spaced for this battery holder: http://www.mouser.com/Search/ProductDetail.aspx?R=12BH321P-GRvirtualkey56100000virtualkey12BH321P-GR
    The battery holder is way bigger than the board ;-)
     
     
    Top:

    Bottom:

    Schematic: DipTrace Schematic - Wireless_ADCTempSender_draft1.pdf
    OSHpark gerbers: Wireless_TempSender_nRF24.zip
  2. Like
    SirPatrick reacted to NatureTM in Parking Sensors   
    I did a lot of work on battery-operated parking sensors for a startup recently.  We used magnetic sensors that are sensitive enough to detect distortions in the earth's magnetic field.  The iron an an automobile distorts the field and either increases or decreases the detected field which is read from the sensor by ADC.  They're quite low power to begin with, plus you can switch them on with a transistor for low duty-cycle sampling, leading to very long operation from battery.
     
    http://www.magneticsensors.com/vehicle-detection-solutions.php
     
    In our project we used the HMC1021 in our case.  I don't think I'm able to share code, but they were very simple to operate, and the datasheet has nice example circuits.
  3. Like
    SirPatrick reacted to roadrunner84 in Problem with bit wise operation   
    Time for a little tutorial in binary!
     
    There are three primitive binary operations:
    invert (negate/not): take one input and give back the opposite (a 0 becomes a 1, a 1 becomes a 0) and: take two inputs and give back a 1 if both inputs are 1 as well (give back 0 if any or all inputs are not 1) or: take two inputs and give back a 1 if any or all inputs are 1 (give back 0 only if no inputs are 1) Visually it looks like this, here A and B are inputs and U is the output
    NOT AND OR A | U A B | U A B | U --+-- ----+-- ----+-- 0 | 1 0 0 | 0 0 0 | 0 1 | 0 0 1 | 0 0 1 | 1 1 0 | 0 1 0 | 1 1 1 | 1 1 1 | 1 In the language C, the bitwise notations for these three operations are ~ (tilde, not), & (ampersand, and), | (pipe, or)
     
    So changing a value in bit X to it's inverted value is written as
    X = ~X;
     
    Now, C does not have a bit variable type, (almost) only integer number variables. So a little about bitwise operations on numbers. For the sake of simplicity I use 4-bit numbers, in reality most variables are either 8-bit or 16-bit (or 32/64-bit on PCs).
    Say I have a variable X and I want to set the least significant bit (the bit most to the right when written), how do I do that? I do an OR operation with the value which holds one 1, which is is the least significant bit position, this value is 1
    X = X | 1;
    X: 0 1 0 0 1: 0 0 0 1 ------- OR 0 1 0 1 Observe that a bit in the result is one if any or all bits directly above it are 1 as well.
    X: 0 1 0 1 1: 0 0 0 1 ------- OR 0 1 0 1 Note that the value of this bit in the variable is not important for the result; the least significant bit is always 1 in the result, because one of the inputs was always 1.
     
    Now if we want to clear that bit? We do an AND with the inverse of 1. Say what? Let's draw it
    1: 0 0 0 1 ------- NOT ~1: 1 1 1 0 X: 0 1 0 1 ~1: 1 1 1 0 ------- AND 0 1 0 0 So by ANDing with the inverse of the desired clear bit, you can actually set it to 0. In C we'll write
    X = X & ~1;
     
    Note that in both these cases ONLY the least significant bit changes, any bits that may be set or cleared in other bit positions are unaffected. This is why you want to use the OR and AND operations, not simple assignments.
    In C there are shorthands for operations on something itself:
    X = X & ~1; equals X &= ~1;
    X = X | 1; equals X |= 1;
     
    So if I write P1OUT |= BIT0; I will only be affecting the bits that are set in BIT0, which is only the least siginificant bit. BIT1 only has the second least siginificant bit set, BIT2 the third least siginificant bit, etcetera.
     
    Advanced bit subjects
    If you want to alter multiple bits, you can first OR them together:
    BIT0: 0 0 0 0 0 0 0 1 BIT2: 0 0 0 0 0 1 0 0 ---------------- OR 0 0 0 0 0 1 0 1 BIT0 | BIT2 Then you can use this to set or clear both bits simultaneously:
    X = X | BIT0;
    X = X | BIT2;
    becomes
    X = X | BIT0 | BIT2;
    in short
    X |= BIT0 | BIT2;
     
    Now if you want to clear both bits in X, you need to use the negated values
    X = X & ~BIT0;
    X = X & ~BIT2;
    becomes
    X = X & ~BIT0 & ~BIT2;
    becomes
    X &= ~BIT0 & ~BIT2;
    visually
    BIT0: 0 0 0 0 0 0 0 1 ---------------- NOT ~BIT0: 1 1 1 1 1 1 1 0 BIT2: 0 0 0 0 0 1 0 0 ---------------- NOT ~BIT2: 1 1 1 1 1 0 1 1 ~BIT0: 1 1 1 1 1 1 1 0 ~BIT2: 1 1 1 1 1 0 1 1 --------------- AND 1 1 1 1 1 0 1 0 ~BIT0 & ~BIT2 X: 0 1 0 1 0 1 0 0 1 1 1 1 1 0 1 0 ---------------- AND 0 1 0 1 0 0 0 0 Note that any bit that used to be 0 stays 0 and any 1 stays 1, except for the bits that are 0 in ~BIT0 & ~BIT2
     
    We could get the value 1111 1010 in another way as well: take the inverse of 0000 0101. As you know by now, 0000 0101 is attained by ORing BIT0 and BIT2
    BIT0: 0 0 0 0 0 0 0 1 BIT2: 0 0 0 0 0 1 0 0 ---------------- OR 0 0 0 0 0 1 0 1 BIT0 | BIT2 0 0 0 0 0 1 0 1 BIT0 | BIT2 --------------- NOT 1 1 1 1 1 0 1 0 ~(BIT0 | BIT2) X: 0 1 0 1 0 1 0 0 1 1 1 1 1 0 1 0 ---------------- AND 0 1 0 1 0 0 0 0 Observe that the result of ~(BIT0 | BIT2) is identical to ~BIT0 & ~BIT2. This property is called Demorgan's law:
    By inverting both inputs and the output of an AND operation, I get an OR operation. By inverting both inputs and the output of an OR operation, I get an AND operation. Since ~BIT0 inverted is ~~BIT0, which is equal to BIT0, this property holds. So I take NOT NOT BIT0 (ie: BIT0) and NOT NOT BIT2 (ie: BIT2) and replace the AND operation with an OR operation. Then I NOT the result once more and get the same result.
     
    So
    X = X & ~BIT0 & ~BIT2;
    becomes
    X &= ~BIT0 & ~BIT2;
    which is equal to
    X &= ~(~~BIT0 | ~~BIT2);
    is equal to
    X &= ~(BIT0 | BIT2);
     
    As a last reminder: BIT0, BIT1, etc. are part of the MSP430 library (msp430.h), not part of the C language itself. So you cannot use these definitions in a PC application unless you create them first.
     
    Exclusive or and asymmetric bitwise operations
    Apart from the three basic operation there is one other operation that might be useful on occasion; the exclusive or. Exclusive or (or XOR in short) is written as ^ (circumflex, xor) and gives back 1 if exactly one input is 1 (give back 0 if no or both inputs are 1)
    XOR A B | U ----+-- 0 0 | 0 0 1 | 1 1 0 | 1 1 1 | 0 XOR can be used to toggle bits. If I have a variable X and want to toggle the least siginificant bit, I XOR X with 1.
    X = X ^ 1;
    or
    X ^= 1;
    X: 0 1 0 1 0 1 0 1 1: 0 0 0 0 0 0 0 1 ---------------- XOR 0 1 0 1 0 1 0 0 X: 0 1 0 1 0 1 0 0 1: 0 0 0 0 0 0 0 1 ---------------- XOR 0 1 0 1 0 1 0 1 As you can see, it works both ways. Be careful when using XOR, as you explicitly have no control over the resulting value; you only make sure it has changed, so keep track of the value it may have had before.
     
    To make our list of operators complete, let's sum up all 16 possible output combinations and see when they're useful and when not.
    NUL AND AND ~ A ~ AND B XOR OR ~( OR ) ~( XOR ) ~B OR ~ ~A ~ OR ~( AND ) ONE A B | U A B | U A B | U A B | U A B | U A B | U A B | U A B | U A B | U A B | U A B | U A B | U A B | U A B | U A B | U A B | U ----+-- ----+-- ----+-- ----+-- ----+-- ----+-- ----+-- ----+-- ----+-- ----+-- ----+-- ----+-- ----+-- ----+-- ----+-- ----+-- 0 0 | 0  0 0 | 0  0 0 | 0  0 0 | 0  0 0 | 0  0 0 | 0  0 0 | 0  0 0 | 0  0 0 | 1  0 0 | 1  0 0 | 1  0 0 | 1  0 0 | 1  0 0 | 1  0 0 | 1  0 0 | 1 0 1 | 0  0 1 | 0  0 1 | 0  0 1 | 0  0 1 | 1  0 1 | 1  0 1 | 1  0 1 | 1  0 1 | 0  0 1 | 0  0 1 | 0  0 1 | 0  0 1 | 1  0 1 | 1  0 1 | 1  0 1 | 1 1 0 | 0  1 0 | 0  1 0 | 1  1 0 | 1  1 0 | 0  1 0 | 0  1 0 | 1  1 0 | 1  1 0 | 0  1 0 | 0  1 0 | 1  1 0 | 1  1 0 | 0  1 0 | 0  1 0 | 1  1 0 | 1 1 1 | 0  1 1 | 1  1 1 | 0  1 1 | 1  1 1 | 0  1 1 | 1  1 1 | 0  1 1 | 1  1 1 | 0  1 1 | 1  1 1 | 0  1 1 | 1  1 1 | 0  1 1 | 1  1 1 | 0  1 1 | 1 As you may see, some operations aren't useful, like the NUL and ONE operator, just use hard values in these cases. The A, B, ~A and ~B operator ignore one parameter, so leave the ignored parameter out.
    Then we find the three btiwise operators AND, OR and XOR and their twins ~( AND), ~( OR ) and ~( XOR ). When I write ~( AND ), read it like X = ~(A & B );
    There are four operators left, which I named ~ AND, ~ OR, AND ~ and OR ~. These operators take one of their two parameters inverted, they are asymmetrical; you cannot flip the two parameters and get the same result. As an example the ~ AND operator is written like X = ~A & B;
  4. Like
    SirPatrick got a reaction from tripwire in CircuitCo Educational Boosterpack LCD Code Example   
    I found a post on the TI E2E community asking questions about the LCD on the educational boosterpack. Someone posted some code for energia and it worked perfect. I took the code and "translated" it to non energia. Here is the forum post. Also here is documentation for the LCD itself from the manufacturer website (PDF). Right now this code prints "hello 43oh.com" . I am going to play with it more later tomorrow. If it is messy code I apoligize, long day at school work in addition to getting use to this platform.. 
     

  5. Like
    SirPatrick got a reaction from Goodfellarich in MSP430G2553 motor speed control with a potentiometer   
    This code just controls the speed of a small 3V DC motor on P1.2. The speed is controlled by a potentiometer on P1.1. Feel free to suggest improvements as I am new to the MSP430.
     

    #include #define motorPin BIT2 #define analogInPin INCH_1 void initADC(); void stopWDT(); void initTimerA(); long map(long x, long in_min, long in_max, long out_min, long out_max); int analogRead(unsigned int pin); void main(void) { volatile unsigned int potentiometerValue; stopWDT(); initTimerA(); initADC(); for (; { potentiometerValue = map(analogRead(analogInPin),0,1023,0,1000); CCR1 = potentiometerValue; // CCR1 PWM duty cycle set by potentiometer } } long map(long x, long in_min, long in_max, long out_min, long out_max) { return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min; } int analogRead(unsigned int pin) { ADC10CTL1 = ADC10SSEL_2 + pin; ADC10CTL0 |= ENC + ADC10SC; for(; { if ((ADC10CTL1 ^ ADC10BUSY) & ((ADC10CTL0 & ADC10IFG)==ADC10IFG)) { ADC10CTL0 &= ~(ADC10IFG +ENC); break; } } return ADC10MEM; } void initADC() { ADC10CTL0 = ADC10ON + ADC10SHT_0 + SREF_0; } void stopWDT() { WDTCTL = WDTPW + WDTHOLD; } void initTimerA() { P1DIR |= motorPin; // PWM out on P1.2 P1SEL |= motorPin; CCR0 = 1000-1; // Setting PWM period CCTL1 = OUTMOD_7; // CCR1 reset/set TACTL = TASSEL_2 + MC_1; // SMCLK configured for up mode }
  6. Like
    SirPatrick reacted to jpnorair in Hydraulic anti-jam control   
    Why don't you just try them both.
  7. Like
    SirPatrick reacted to zaraudio in hello for socal   
    I am currently using the 2553 with the cc8530 in a consumer product to be launched in june.  plus many other things brewing in my head.  
  8. Like
    SirPatrick reacted to LariSan in LaunchPad Proto Plate- from Ponoko   
    I had a few of these "protoplates" made-- I fell in love with the one from AdaFruit for the BeagleBone and really wanted one for the LaunchPad and had some made. 
    (I have to thank Bart, if he's on here, for really making my first Ponoko trial-run so smooth). 
     
     
        So here is where you can order the sheet.
    It's 14 total plates on the Plastic- Acrylic- Clear- 3mm- P3 sized sheet, which comes out to be about 3.50 for each plate- total about 46.50 (Bart had free shipping since he's a regular user at Ponoko). 
     

      I'm sure there is a more efficient way to arrange these to get more on the same sheet (there was a lot of extra plastic that wasn't used). This was a trail run for me. 
     
    It comes in a large sheet, where you only need to pull off your plate
      I left the backing on the plate--     Added the breadboard:    
    these breadboards from Mouser (I get them in packs of 10 so it comes out to be about 4.95 a piece)
      The hardest part was to figure out how to connect the LaunchPad to the sheet.  Even though it's nice that the rubber feet were already included... it turned out to be inconvenient. 
    The BeagleBone and the Arduinos have screws that allow you to use standoffs.  In this case after trying: hot glue, epoxy, these scrapbooking "zots" (super strong adhesive tapes in dot shape) and double stick tape and found out that all of them don't adhere to the rubber well.  What's worked is Crazy Glue.      Put it on the LaunchPad, set it down and let it dry...    then I peeled off the backing.        I'll get to test these in a workshop soon, but so far I like them, but plan on changing a few things.  I have about three extra that I wouldn't mind sending to anyone who wanted to see it.    It's hard to know which direction is up... I have two sleds and one is right handed and the other is left handed... I guess if I just removed the logo all together I could have it be either right or left handed      This is what I think my next one will look like, but I'm completely open for any suggestions!     Hope that's helpful, I've included the files to make the edits in my dropbox (it's in illustrator and the forum doesn't like the format for some reason). https://www.dropbox.com/sh/6tho7jrplryvyhl/PJAJ22XqpQ
    Final- LaunchPad Proto-Sled v1.0- Bart.zip
  9. Like
    SirPatrick reacted to JeffersonJHunt in ePaper Hour Meter   
    Special thanks to the authors of the following projects - ePaper Calendar and bilder.org !
     
    I picked up the ePaper display and the associated header from the good folks at SparkFun!
     
    I needed to build an hour meter for a 240v heater in the shop. I could have used a COTS power adapter and a mechanical hour meter, but I couldn't pass up the chance to use ePaper.
     
    The meter tracks total time since last reset (via a jumper) and the current/last amount of time the unit ran. I used an ePaper display so the display would be readable even when the unit was powered down.
      The code is very run of the mill stuff sans the small bit of code to rotate run time between 3 chunks of info memory with a small error correction routine. This not only protects from a bad write (say during a power cycle) but also effectively triples the endurance of the flash. Look in the flash.c and flash.h files.   The code is fairly clean, but not terribly optimized. It weighs in at ~2016 bytes so it just about maxes out the g2211 I used.   There is a video I took just before final assembly :    hour-meter-v1.zip

  10. Like
    SirPatrick reacted to geodave in Solar Driveway Light to MSP430 Wireless Sensor Node   
    Greetings!  I am new to the forum and this is my first solo microcontroller project.  Please be kind to me as I am a Geographer and by no means a programmer or electrical engineer.  Stupid questions should be expected.    
     
    The basic idea of this project is to convert a $3-4 solar light found at Lowes and Home Depot hardware store (here in the US) into a wireless remote sensor node.  The node will utilize an MSP430G2553 MCU and a nRF24L01+(w/ spirilis library) wireless module to send light intensity (photoresitor that came with solar driveway light), soil moisture (design from http://gardenbot.org), and soil temperature data (10k thermistor coated in silicon) wirelessly from my garden to another MSP430G2553 and nRF24L01+ sitting on top of a Raspberry Pi.  This data will then be sent over the Raspberry Pi UART to a python script running on the Raspberry Pi which logs the data into a CSV and JSON file (code inspired by Uberfridge).  An Apache server will also run on the Rapsberry Pi and the JSON data will be displayed via the Javascript Flot chart library.  The node on the Raspberry Pi will also have a transistor that switches a water Solenoid attached to my garden hose based upon the soil moisture.        
     
    Photo 1.  The $4 light from Lowes Hardware.  Portfolio Landscape brand Model #0379420 (http://tinyurl.com/cn4e684)

     
    Photo 2.  I like that it has a nice battery compartment and comes with a 800Mah AA Battery.  

     
     
    Photo 3.  The inside of the light.  Contains a chip which boosts the 1.2v battery to 5.0v to power the LED.  Comes with an inductor and diode that can be reused.

     
    I taught myself Eagle Autocad and created a schematic/board to replace the stock board inside the solar light.  My board utilizes a Texas Instrument TPS61097 (free sample) which converts the 1.2v from the batter to 3.3v to power the MSP430.  Version 1 of the board is shown below with just the power circuitry populated (Photo 6).   I put a jumper wire on the TPS61097 between the EN and VIN because I wasn't able to get the bypass switch (Page 16 of the schematic http://www.ti.com/lit/ds/symlink/tps61097-33.pdf ) to work correctly.  I had 200k resistors on R1 and R2 (actually 2x100k 1% in series each...didn't have any 200k on hand) which didn't work (bypass switch stays on) so I jumpered EN and VIN and now get the full 3.3v.  I would like to get this bypass feature enabled.  Any ideas where I am going wrong here?  I assume the resistor values are incorrect for the 1.2v battery.    
     
    Photos 4 and 5.  Board Mockups from OSHPark
              
     
    Photo 6.  V1.0 of the board received 3/20/2013. Partially populated (no time!!!).  Two green wires are from stock photoresistor (not yet connected).

     
    Photo 7.  Schematic for v1.0

     
    Current Project Status:  Basic code for Raspberry Pi done (python and Flot charting), code written that reads sensors and sends comma delimited sensor data over Raspberry Pi UART,  v1.0 solar light board done and receive today from OSHPark (3/20/2013).
     
    Current Activities:  Waiting for my second child to be born and testing the charging and booster circuit. 
     
    Still to do:  Get nRF24L01+code working with my existing code and design Raspberry Pi Node (current version on rough protoboard board).   I did start playing with my nRF24L01+ modules and was able to send my name through the character buffer array.  I need to find the best way to send this data through the nRF24L01+ module and print it to the UART attached to the Raspberry Pi.     
     
    I hope you guys enjoy my project idea and with your help I will hopefully finish.  I will post schematics/boards, code, etc when it is more complete.  My wife is due next week so things will likely progress slowly.   
     
    The code I do post will likely be messy.  If you like my project feel free to help me clean it up but please do explain whatever you do in layman terms.  I am not as lay as I use to be with electronics/programming but much more lay than most of you folks!  Cheers!
  11. Like
    SirPatrick reacted to xv4y in Code source for VFO using AD9850/AD9851 DDS   
    Hi,
     
    This will ring a bell to radioamateurs (HAM radio) but other may just ignore...
    I have posted to my blog a code for a simple VFO (Variable Frequency Oscillator) or better said an RF frequency generator using an AD9850 DDS chip.
    This code is simple and has no special trick but might give you inspiration.
     
    http://xv4y.radioclub.asia/2013/03/19/code-source-vfo-avec-dds-ad9850ad9851-et-launchpad-msp430/
     
    The pins are "wired" for my WSPR agile beacon generator kit, but everything can be changed to your taste or needs.
    The text of the blog article is in french but has no additional information than the one in the source code (commented in english).
    The needed libraries are on my download page :
    http://xv4y.radioclub.asia/boutique/docs/
     
    Regards,
    Yannick.
  12. Like
    SirPatrick reacted to geodave in Hello from Raleigh, North Carolina   
    Greeting!  I am a Geographer by trade with a background in remote sensing. I originally discovered electronics and microcontrollers when trying to find an economical way to automatically control the temperature of my BBQ smoker.  I stumbled upon the Arduino based "Linkmeter" PID Smoker controller project (Google it), built a couple of those, and fell in love with the idea of designing and building my own electronics.  It has been a long and slow learning process but forums like this have really made all the difference.  I am hoping I can combine all of the knowledge I have collected over the past couple years to build a solar powered wireless garden monitoring and watering control system based on the MSP430G2553 and Raspberry Pi.  Perhaps another post of that soon...    
     
    I stumbled upon the MSP430 line of microcontrollers about three months ago and I am in love.  I stalled out on the Arduino platform because I kept running into coding issues that I had difficulty troubleshooting.  I like the Launchpad platform much better than the Arduino because of the debugging capabilities of CCS.  I am learning about 10 times faster with the debugger.  Thanks for all the help in advance!   
  13. Like
    SirPatrick reacted to larsie in Garage door opener   
    I'm trying to make a garage door opener using some cheap CC2500 boards bought through a group-buy at 43oh.com (2 USD each) and a really nice board designed by RobG. I've made a prototype first, and it seems to work, but is not very pretty. I need to maybe make it more compact and make a case for it. Here's a picture:



    The code is definitely not finished, but you can download it here if you want to look at it. It's based on the TI CC2500 library (not SimpliciTI, which would probably have been a natural choice). I'm using the bitbanging version, as I didn't have any surface mount MSP430G2553.

    I guess maybe I should put the battery beneath.
  14. Like
    SirPatrick reacted to GG430 in Starry Sky with LEDs   
    This was a present for my daughters first birthday. Actually I wanted to have it ready one year earlier before her real birthday but had some project delay ;-)
    The plate is mounted to her rooms ceiling close to her bed and there is no day going to bed without her switching it on. She had her 4th birthday back in January.
     
    It's a starry sky with 32 LEDs showing 5 signs (Gemini, Cancer, Capricorn, Aries and Virgo). I was only able to share 3 LEDs and that was the minimum I needed. A MSP430F2012 is driving two TLC5940 on a proto board, dimming the LEDs in and out. Actually I planned to etch a PCB but then I stayed with the proto. Three buttons are controlling the different operating modes. Due to the lack of ports I added different resistors to the buttons which I measure with the ADC once triggered by an interrupt to see which one was pressed. This reduces the required port to one for three buttons. The code is in Assembly, guess today I'd write it in C. I added some features over time, like switching all LEDs to full power to have an additional light in the room.
     
    There is a funny story behind the signs for me. I had chosen the signs of my wife, dad, mom, myself and my daughters projected date of birth which was Capricorn. But unfortunately live is sometimes not as predictable as we think and my daughter took another 12 relaxing days with her mom and slipped over being an Aquarius. Since I already had finished the wooden plate I didn't change it anymore. So her sign is the wrong one in the project. I'm looking forward to tell her the story in a couple of years
     
     
     


     


     
    StarrySky.ppt
  15. Like
    SirPatrick reacted to rebeltaz in Coffee Pot Fish Tank   
    My girlfriend wanted a Betta fish for Valentine's Day. When we got it home, I realized that it was a Tropical fish needing warm water - a slight problem in the winter. Using a coffee pot and the MSP430, I hacked together a (I think) pretty cool fish tank that not only looks good, but keep the little guy at a happy 75-80 degrees. Rather than rewrite everything, I am just going to link to my web page - I hope that is ok?
     
    http://www.robotsandcomputers.com/robots/projects/cpfishtank.htm
     
     

  16. Like
    SirPatrick reacted to vicvelcro in Critter Catcher - Live Trap with a Brain   
    Currently written using Energia. If I can ever figure out Code Composer Studio, I'll probably redo it with that.
     
    Photos (the attachments beginning with "SAM_xxxx"), hand written build notes (in photos), and hand drawn pseudo-schematic (in photo) are in the archive files attached to this post. Photos that didn't appear in the sequence were too blurry to include and didn't contain anything not already in one of the other photos. I added some comments to the code, in the body of this post - the attached code has fewer comments.
     
    So, this is an 'intelligent' live trap. A creature must be far enough inside. If not far enough, then door stays open. Door will only close if creature would be unable to flee via the exit before the exit would be able to close.
     
    For now, I am using an IR LED as an emitter and another IR LED as a receiver. This is because I don't want visible light to affect the system. Later, I intend to use a laser which is obviously a fixed wavelength and I will then choose a sensor very narrowly tuned to that wavelength. Hey, why not?!?
     
    The code is certainly messy, but that's my current level of skill. It will improve as I improve. Suggestions, advice, general comments, and critiques are welcome and appreciated. If something belongs in a function, hit me with it. If you know a better way to implement "if" statements that the way I have done it, hit me with it.
     
    * I would like to use a low power mode, to extend the battery life. I have mentioned this in another thread. Anyone willing to walk me through an implementation of low power mode, I'm open for input. I do not want arbitrary code, though. I won't 'just paste' anything I can't understand or decipher. Commented code with clear explanation would be much appreciated.
     
    Yes, this thing does work. And it works quite well for its intended purpose. I think I will scale it up to 'varmint' size in the near future.
     

     
     
    THE CODE
     
     
     
    // The pin assignments are applicable when a 2553 MCU is used. // If you will use any other MCU, check the pin layout to see if changes are necessary. #include <Servo.h>   Servo myservo;  // create servo object to control a servo   int posm = 5;   // variable to store the servo position int posz = 5;  // starting position of servo boolean moveServo = 0; int serswpdeg = 135; // define the limits of the sweep range for the servo int swait = 5; // sets global wait delay value int servport = P2_4; // sets the port number for servo signal line const boolean powind = P2_1; //power indicator port number //const byte tripwire = P2_5; //the beam generator pin assignment - currently not in use, it is wired to power supply to be continuously on const byte tripdet = A4; //the port used as tripwire detector const byte trapdoor = P2_2; //the actuator or relay or solenoid to be triggered - which pin const byte trippedled = P2_0; //the LED port to indicate tripped const byte occuled = P1_5; //the LED port to indicate hopper is occupied const byte occusen = P2_3; //the sensor port to detect when hopper is occupied const byte reswitch = P1_3; //count reset switch port - serial data for debugging - can be removed const byte sens = 20; //how much sensor must decrease to activate trip const unsigned int wait = 1; //sets the wait time during major loops const unsigned int caloop = 1000; //the number of normal runs before recalibrating detector const unsigned int calcount = 1000; //number of times to sample for calibration of sensor const unsigned int detcount = 250; //number of times to sample for confirmation of detection int basis = 0; //the averaged number we compare against to determine if trigger occurs long light = 0; //sets the level of light before beginning boolean tripstate = 0; //sets whether the trip is currently triggered unsigned long tripcount = 0; //how many times trigger has been activated in total boolean reswitchval = 0; // stores value of reset switch boolean occupied = 0; // when a sensor is implemented, this will hold the state of the sensor unsigned int loopx = 0; //counts loop repetitions for calibration unsigned int loopy = 0; //counts number of total passes for detection unsigned long totaal = 0; //keeps a running total of light readings to average out unsigned long totaal1 = 0; //keeps a running total of light readings to average out void setup()   {   Serial.begin(9600); //  pinMode(tripwire, OUTPUT); // it is hard wired to the power supply to be continuously on   pinMode(trapdoor, OUTPUT);   pinMode(tripdet, INPUT);   pinMode(trippedled, OUTPUT);   pinMode(occuled, OUTPUT);   pinMode(occusen, INPUT);   pinMode(powind, OUTPUT);   pinMode(reswitch, INPUT); // if using external switch   pinMode(servport, OUTPUT); // pinMode(reswitch, INPUT_PULLUP); // if using onboard switch - not sure if this line is even correct syntax (probably not)   myservo.attach(servport);  // attaches the defined servo pin to the servo object //  digitalWrite(tripwire, HIGH);  // turning on tripwire   myservo.write(5); // twitches the servo so that it won't jitter later   myservo.write(0); // twitches the servo so that it won't jitter later   myservo.write(5); // twitches the servo so that it won't jitter later   digitalWrite(trapdoor, LOW);   // turning off trip   digitalWrite(trippedled, LOW); //turning off tripped indicator   digitalWrite(occuled, LOW); //turning off occupied indicator   digitalWrite(powind, HIGH); // turning on the power indicator   digitalWrite(servport,LOW); // turns off the servo data line for now   } void loop() { //readings to set the sensors based on averaged readings   if (tripstate != 1)   {   totaal=0;   totaal1 =0;   light=0;   for(loopx =0; loopx < calcount; loopx++)     {   light = analogRead(tripdet);   totaal = totaal1 + light;   totaal1 = totaal;   delay(wait);     }   light = totaal/loopx;      // divide the total readings by number of reads   Serial.print("Sensor Calibrating to ");   Serial.println(totaal/loopx);   digitalWrite(powind, LOW);   delay(100);   digitalWrite(powind, HIGH);   totaal = 0;   totaal1 = 0;   } basis = light - sens;  // setting trip sensitivity // after every (caloop) the detector will recalibrate     for(loopy = 0;loopy < caloop; loopy++)     {        for(loopx =0; loopx < detcount; loopx++)      //readings to see if the sensor is dark        {        light = analogRead(tripdet);        totaal = totaal1 + light;        totaal1 = totaal;        delay(wait);        }     light = totaal/loopx;     totaal=0;     totaal1=0; reswitchval = digitalRead(reswitch);   if (reswitchval == HIGH)   {     tripcount=0;   }     if (tripcount != 0)   {     digitalWrite (trippedled, HIGH);   } else   {     digitalWrite (trippedled, LOW);   } occupied=digitalRead(occusen); if (occupied == HIGH)   {     digitalWrite(occuled,HIGH);   } else   {     digitalWrite(occuled,LOW);   }          if ((light < basis) && (tripstate != 1))          // testing if the sensor was in the dark          {          tripcount++;          digitalWrite(trapdoor, HIGH);  // turning the trip in port on if the sensor is dark          (tripstate = 1);          (moveServo = 1);          }        else        {          if ((light > basis) && (tripstate != 0))          {       digitalWrite(trapdoor, LOW); // turning it off if not        (tripstate = 0);        totaal = 0;          totaal1 = 0;            }        }     if (moveServo == 1)     {     Serial.println(" ");     Serial.print("Moving the Servo");     Serial.println(" ");     for(posm = 5; posm < serswpdeg; posm ++)  // goes from 0 degrees to 180 degrees         {                                  // in steps of 1 degree                myservo.write(posm);              // tell servo to go to position in variable 'pos'                delay(swait);                       // waits 15ms for the servo to reach the position         }                  if(posm>0)       {     for(posz = serswpdeg; posz >= 6; posz --) // returns servo to 0 degrees         {           myservo.write(posz);           delay(swait);         }       }       (moveServo = 0);     }        Serial.print("Reading ");        Serial.print(light);        Serial.print("   ");        Serial.print("Trip on ");        Serial.print(basis);        Serial.print("   ");        Serial.print(light-basis);        Serial.print("   ");        Serial.print("Trip State ");        Serial.print(tripstate);        Serial.print("   ");        Serial.print("Time to next Calibrate ");        Serial.print(caloop-loopy);        Serial.print("   ");        Serial.print("Occupied ");        Serial.print(occupied);        Serial.print("   ");        Serial.print("Times Tripped ");        Serial.print(tripcount);        Serial.println("");  //  delay(wait);  } }    
     
    Laser Trip Trap v10 - Energia Code.rarSAM_0055.rarSAM_0056.rarSAM_0057.rarSAM_0059.rarSAM_0060.rarSAM_0061.rarSAM_0062.rarSAM_0063.rarSAM_0064.rar

  17. Like
    SirPatrick reacted to gwdeveloper in Is it just me or tonight TI doubled LaunchPad price?   
    I've been watching this thread for a bit. Considering me walking the line on this one. As an owner of two currently operating businesses, I see TI's point and need in raising their prices.
     
    Last year I raised my per irrigation zone rates and lost several customers, but only for a few months. They came back after realizing the service and finished products I offered were better than my competitors and my project turnover rates are faster too. So while I took a hit for a short time, revenue and customer satisfaction are higher.
     
    Yes, TI's rate increases bite but think about it... An almost announcement of the g2995?? What else are they hiding? What does the LP v1.6 look like? Or v1.7? TI, let us see the roadmap and give us a bit of encouragement about the future of your products.
     
    In my experience, TI's products and services have been top notch. Their e2e community has been extremely helpful. Their data sheets are flat out the easiest to read and most consistent among product families.
     
    Also, the 43oh community has greatly increased usage and recognition. I believe more projects and boosterpacks have poured out of us here than the whole of the users on E2E. Maybe we (mostly meaning bluehash) can work on expanding our partnership with TI? I for one, plan to stick with the MSP430 for smaller projects and I'm really enjoying the Stellaris line, issues and all.
  18. Like
    SirPatrick reacted to RobG in Audio Spectrum Analyzer - Part Deux   
    This is a continuation of this project.
     
    While playing around with my WS2811 strips, I figured that it would be nice to have a board like this one.
     
    Could be used with one or two EQ chips and as a stand-alone board.
     
    The question is: with booster pack support or without?
     

  19. Like
    SirPatrick got a reaction from larryfraz in DIY MSP430 wifi connectivity with retail router   
    I have been working on a few different projects that could be described as wireless sensor nodes. Just to get something working I decided to hack a retail router to give my MSP430 wireless capabilities. The first step was to install OpenWRT Linux onto the router to make it configurable. After that I mounted the file system onto a flash drive that was using the built in USB port on the router. From there I broke out the convenient 3.3v  serial connection and hooked it up to my MSP430. Currently I am working on a full write up that will include compiling OpenWRT from source and detailed step by step instructions to install all the needed packages. I am also finishing up some scripts that should automate the hard stuff and give your launchpad a wireless connection in no time.
     
     
    Decided I would add some some pictures and examples for everyone to look at while I finish the write up / automation scripts. This is by no means a finished or polished project. 
     
    Here is a link to the Imgur album with short descriptions.
    http://imgur.com/a/xzga5
     
     
     
     
    And here is a video of me using the wireless capabilities to trigger a relay. I will update this post when I finish everything else. 
    http://www.youtube.com/watch?v=aU0LfrJBSKE
     
     
     
     
  20. Like
    SirPatrick reacted to LariSan in Is it just me or tonight TI doubled LaunchPad price?   
    I'm a little afraid that I'll step into a big pile here, but I wanted to offer a couple of nuggets *please keep in mind that I usually only deal with University Partners, so I come from a slightly unique perspective. 
     
    The LaunchPad has pretty much changed TI's place in the Microcontroller market and especially in Education. 
    For me, I've been able to open up a lot of educational doors with the price point and what the kit could offer. However, the past year I've been watching it slow down a bit as the "4.30" on it's own isn't as compelling. The requests started to come in that I find ways to bundle the LaunchPad + Breadboard + Wires or , LaunchPad + BoosterPack combo or LaunchPad + Book + Training material... 
    So, I went to look and see how I could get some of these requests fulfilled. 
    Turns out--
    The eStore can't do much than stock TI Standard kits, nor can they really bundle. 
    DigiKey, Mouser, Newark -- have bundling options, but it's horrific to set these up, let alone have to manage the paperwork associated with the bill backs for services. 
    I didn't even try with Arrow and Avnet because they weren't interested in anything that didn't generate serious money (e.g. Big Customers)...
     
    So, I turned to some of the "hobby" distributors (e.g. Sparkfun, some local ones in India and Europe), went to a couple of conferences, met with some of the decision makers...
    and asked them, "What can I do to get you to stock LaunchPads and offer "bundles" and trainings/services.?" All of them were interested, but when they saw that they would be buying the LaunchPad at the same price that TI was selling it for... backed out. 
    There was absolutely no money in it for them. 
    It costs money to inventory, stock, manage paperwork-- and time. (that's not even developing training and marketing) Sure, some universities would pay for value added services, but what was incentivising someone to buy from them (person providing the service)? Plus, the amount of effort + the pay out... for most of them wasn't worth it. 
    I talked to no fewer than fifteen different educational distributors... and got a similar story. It started to become really clear that TI was indirectly competing against the same people that we needed to offer more/better services (at least in Education). 
     
    To make sure I didn't give up on the 4.30 model... I tried a few things. (A little lengthy story, but I think this illustrates the best one)
    I donated the entire LaunchPad inventory to a few of my partners (IEEE groups who were doing ebay purchases and bundles). 
    Great for the first semester, but come re-order time-- I had run out of budget. 
    So, the IEEE group had to switch and instead used the Arduino... and found students were willing to pay the 50.00 (when the previous was 24.00). 
    When semester came around and I had budget, I called asked them if they wanted to try again... and they declined me. They would rather set up the store to not have to manually switch everything over just because I couldn't donate the kits!
    So, I asked, how about buying them? I'll make sure that you can always purchase them at a discount, (which was almost nothing because $4.30 was pretty much rock bottom). 
    Declined again-- with the Arduino the IEEE group was able to get them at 21.00 and reselling the boards for 30.00. That was 9.00 of extra margin they could use, if I wasn't giving them the LaunchPads free... all the time, there was absolutely no incentive for them to move over. (Insert "using Industry tools blah blah blah" argument, still couldn't switch them over). 
     
    Granted, one IEEE group is NOT everyone else, but the concerns were similar. 
    It showed me (at least in my space) that the only way I could push LaunchPad was through my program-- which is limited by my budget and what other things that I wanted to accomplish that year. The only way that I could grow LaunchPad in Education--> was increasing the level of service and offerings around LaunchPad--> which was beyond what TI could do on our own and  I could only accomplish by getting good partners-->and the only way to get good partners... was frankly-- help them make money. Successful Partner with LaunchPad meant Successful TI University Program. 
     
    So, although it sucks right now, I really see this as a good idea-- for a long term strategy. 
    We really could have done a much better job communicating the price change... it is never fun to find out on your own. 
    There were always be TI Deals, half off coupons, Tech Day incentives.... heck, come visit me at any of my University visits, write a request, or our trade shows and you will be able to get a LaunchPads for free or a discount. We owe a lot to the community and want to continue to support it, but at the same time we're fairly realistic that a community is a lot more than just cheap hardware, that's what got us up and running and started, but now we really need to focus on enabling the very people that helped build it up-- enabling them to potentially create a business model around all the work that is being put in. Take a look at the Arduino, it was an open sourced hardware, intuitive user experience platform (the LaunchPad is also Open Hardware and now has Energia), but what really differentiates the Arduino from LaunchPad is the fact that people can make money by being part of the ecosystem-- through their own Hardware, Software contributions, Training, Bundling... etc. etc. 
     
    I'm by no means the official LaunchPad communication channel,  but I'm a rather large constituent of it-- we're working hard on the next few steps we need to take on finding ways to grow -- and how honest, vocal and engaged everyone is critical for that (WE ARE Listening), so please keep letting us know what you think. 
     
    Anyways, that's just my 2 cents... 
    -Larissa
  21. Like
    SirPatrick got a reaction from ashwini.nazarkar in Heart rate monitor using MSP430   
    Sure we can help, but first we need to know more about the problem. Some helpful things would be
    Code you are working with More information on the ECG and how you are getting the data to the msp430 (serial.SPI,etc) Any schematics / wiring diagrams  
    Once you give us that we can start assisting. 
  22. Like
    SirPatrick reacted to oPossum in Efficient muldiv() and scale() functions for 2000 series   
    One of the limitations of the C language is that multiplication truncates the result to match the size of the multiplicands. So if you multiply two 16 bit numbers, the result is limited to 16 bits despite 32 bits being needed to represent all possible results. The fix for this is to cast one of the multiplicands to a larger type. Unfortunately this results in the use of a multiply library routine that is larger and slower than necessary. Division has a similar problem - the quotient, dividend, and divisor are all the same size.
     
    The way I fix these limitations is to write assembly code that is compact, efficient, and well suited to specific tasks. The muldiv() function provided here will take 16 bit unsigned values and do a multiply to a 32 bit intermediate result and then divide back down to 16 bits. It makes some simple tests on the arguments to optimize the code path.
     
    One specific case where this muldiv() function is useful is scaling one range of values to another. For example taking the 0 to 1023 range of a 10 bit ADC and scaling to some actual unit of measure.
     
    A helper function function can be used to allow clearly written code...
     
    uint16_t muldiv_u16(uint16_t a, uint16_t b, uint16_t c); inline uint16_t scale_u16(uint16_t in, uint16_t in_low, uint16_t in_high, uint16_t out_low, uint16_t out_high) { // For guaranteed correct results: // in_low <= in <= in_high // in_low < in_high // out_low < out_high // return out_low + muldiv_u16(in - in_low, out_high - out_low + 1, in_high - in_low + 1); } Sample usage...
     
    // Read 10 bit ADC value - range of 0 to 1023 const uint16_t adc = readADC(); // ADC reference votlage is 2.5V, so convert to a range of 0 to 2500 mV const uint16_t mv = scale_u16(adc, 0, 1023, 0, 2500);    
    Note that there are constraints on the values passed to the function. All are unsinged 16 bit integers, and must fall withing the constraints to ensure a correct return value.
     
    Signed integers can also be used because the constraints will result in unsigned values being passed to the muldiv() function...
    inline int16_t scale_i16(int16_t in, int16_t in_low, int16_t in_high, int16_t out_low, int16_t out_high) { // For guaranteed correct results: // in_low <= in <= in_high // in_low < in_high // out_low < out_high // return out_low + muldiv_u16(in - in_low, out_high - out_low + 1, in_high - in_low + 1); }    
    The in_low <= in constraint can easily be removed if needed...
     
    int16_t scale_i16x(int16_t in, int16_t in_low, int16_t in_high, int16_t out_low, int16_t out_high) { // For guaranteed correct results: // in_low < in_high // out_low < out_high // -32768 <= return <= 32767 // return (in < in_low) ? out_low - muldiv_u16(in_low - in, out_high - out_low + 1, in_high - in_low + 1) : out_low + muldiv_u16(in - in_low, out_high - out_low + 1, in_high - in_low + 1); }  
     
    The other constraints could be reduced or eliminated using C++ templates. (exercise for the user)
    ; ;    Copyright (C) 2013  Kevin Timmerman ; ;   This program is free software: you can redistribute it and/or modify ;   it under the terms of the GNU General Public License as published by ;   the Free Software Foundation, either version 3 of the License, or ;   (at your option) any later version. ; ;   This program is distributed in the hope that it will be useful, ;   but WITHOUT ANY WARRANTY; without even the implied warranty of ;   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the ;   GNU General Public License for more details. ; ;   You should have received a copy of the GNU General Public License ;   along with this program.  If not, see <http://www.gnu.org/licenses/>. ;     .cdecls C, LIST, "msp430.h"                 ;                                                 ;     .text                                       ;                                                 ;                                                 ; return a * b / c     .def    muldiv_u16                          ; uint16_t muldiv_u16(uint16_t a, uint16_t b, uint16_t c)     .def    muldiv_u8                           ; uint8_t muldiv_u8(uint8_t a, uint8_t b, uint8_t c)                                                 ;                                                 ; muldiv_u16:                                     ;                                                                                               ; --- Multiply ---     push    R10                                 ; Accumulator MSW     push    R11                                 ; Accumulator LSW                                                                                               ; R12 a                                                 ; R13 b                                                 ; R14 c                                                 ; R15 b shift register LSW                                                 ;     clr     R11                                 ; Clear accumulator LSW     mov     R12, R10                            ; Copy a to accumulator MSW                                                 ;  (assume multiply by zero)     tst     R13                                 ; Multiply by zero?     jeq     div16                               ; Yes, skip multiply...     cmp     R12, R13                            ; Make R12 smaller than R13 to     jhs     no_swap16                           ;  do multiply as quickly as possible     xor     R12, R13                            ;     xor     R13, R12                            ;     xor     R12, R13                            ; no_swap16:                                      ;                                                   clr     R10                                 ; Clear accumulator MSW     clr     R15                                 ; Clear MSW of b shift                                                  clrc                                        ;                                                   jmp     mul16_begin                         ; mul16_add:                                      ;     add     R13, R11                            ; Add b to accumulator     addc    R15, R10                            ; mul16_shift:                                    ;     rla     R13                                 ; Shift b     rlc     R15                                 ; mul16_begin:                                    ;     rrc     R12                                 ; Shift a, test lsb     jc      mul16_add                           ; lsb is 1, add b...     jne     mul16_shift                         ; lsb is 0, but more 1 bits remain...                                                 ;                                                 ; --- Divide ---                                                 ; R13/R10/R11 Dividend / Quotient shift register                                                 ; R14 Divisor                                                 ; R15 Bit count div16:                                          ;     mov     R10, R12                            ; Copy MSW of accumulator to result                                                 ;   (assume divide by zero)     tst     R14                                 ; Divide by zero?     jz      div16_exit                          ; Yes, all done...     mov     #1, R15                             ; 16 bit quotient div16_shift:                                    ; R10 <- R11     rla     R11                                 ; Shift     rlc     R10                                 ;                                                 ; Greater than or equal to divisor?     jc      div16_sub                           ; Yes...     cmp     R14, R10                            ;     jlo     div16_next                          ; No... div16_sub:                                      ;       sub     R14, R10                            ; Yes, subtract     bis     #1, R11                             ; Set bit in result div16_next:                                     ;     rla     R15                                 ; Dec bit count     jne     div16_shift                         ; Next bit...     mov     R11, R12                            ; Return result in R12 div16_exit:                                     ;     pop     R11                                 ;     pop     R10                                 ;     ret                                         ;
  23. Like
    SirPatrick reacted to JWoodrell in First commercial board (something that someone paid me for)   
    the last thing it saw before things went dark and the screws got tightened down.
     
    project *complete*, tested and will be delivered first thing in the morning
     
     

  24. Like
    SirPatrick reacted to JWoodrell in First commercial board (something that someone paid me for)   
    Hey guys I am pretty happy, I actually got it to work and program and whatnot.
     
    This is the first thing Ive made with a MSP430 that I'm actually getting paid to do.
     
    It is my controller interface project, and a friend at work is paying me $40 bucks to make it. which is around what the original controller conversions go for online (I was just gonna charge him cost, but he threw out $40.
     
    not bad for $21 bucks in parts including the legitimate original controller (I'm picky the remake ones don't feel right)
    I paid $10 for the controller. and $11 for the PCB and components.
     
    also I figured out the problem i was having with the little BGA regulator.  I was working with it like the rest of the components, but in reading on it, the little solder balls are lead free, which meant they were not really melting at the temperatures i was working at.  so once I got the new ones in, i cranked up the oven to lead free temps, and poof it soldered on, and worked the first time.  I will still probably not use them again once i use up the 10 i bought, just because the time it takes to position and handle it being as picky as it is.
     
    anyway here is the board being programmed from the launchpad, as a side note my next ones will have a 3 pin programming header so i don't have to hook up VCC separately.
     
    it just about gave me a heart attack when i first connected to it to load the program it threw an error saying the security fuse had been blown, but after taking it off and re plugging it on the launchpad, it was happy. 
     
     
     
     
     

  25. Like
    SirPatrick reacted to oPossum in 2^N for real numbers using integer math   
    When working with electronic music (MIDI synth and such) it is sometimes necessary to adjust pitch by units of octaves, semitones, or cents.
     
    An octave is a 2:1 ratio. So the ratio between any number of octaves is 2^N. This is a simple bit shift. Easy.
     
    A semitone is 1/12 of an octave (typically), so the ratio for that is 2^(N/12). A cent is 1/1200 of an octave, so the ratio for that is 2^(N/1200). Can't use bit shifting for that!
     
    The C stdlib provides the pow() function that can be used for these calculations, but it uses rather slow floating point math.
     
    This code will do it with relatively fast fixed point integer math. This code could easily be adapted to almost any base and exponent by changing the look-up tables. It uses the property of exponents that 2 ^ (1 + 2 + 4 + 8) == (2 ^ 1) * (2 ^ 2) * (2 ^ 4) * (2 ^ 8)
     
     
    // // 2 ^ (n / (1200 * 8192)) // // n = 1 / 8,192 cent //   = 1 / 819,200 semitone //   = 1 / 9,830,400 octave // // range of n: -134,217,727 to +78,643,199 //            = -13.65 to +7.99 octaves // // returned value is 8.24 fixed point // // + exponents in 8.24 format static const uint32_t etp[27] = {     0x01000001,                     // 00000001  1.0000000705     0x01000002,                     // 00000002  1.0000001410     0x01000005,                     // 00000004  1.0000002820     0x01000009,                     // 00000008  1.0000005641     0x01000013,                     // 00000010  1.0000011282     0x01000026,                     // 00000020  1.0000022563     0x0100004C,                     // 00000040  1.0000045127     0x01000097,                     // 00000080  1.0000090254     0x0100012F,                     // 00000100  1.0000180509     0x0100025E,                     // 00000200  1.0000361021     0x010004BB,                     // 00000400  1.0000722054     0x01000977,                     // 00000800  1.0001444161     0x010012EE,                     // 00001000  1.0002888530     0x010025DE,                     // 00002000  1.0005777895     0x01004BC1,                     // 00004000  1.0011559129     0x01009798,                     // 00008000  1.0023131618     0x01012F8B,                     // 00010000  1.0046316744     0x0102607D,                     // 00020000  1.0092848012     0x0104C6A1,                     // 00040000  1.0186558100     0x0109A410,                     // 00080000  1.0376596592     0x0113A513,                     // 00100000  1.0767375682     0x0128CC11,                     // 00200000  1.1593637909     0x01581889,                     // 00400000  1.3441243996     0x01CE81F4,                     // 00800000  1.8066704016     0x0343994D,                     // 01000000  3.2640579400     0x0AA77169,                     // 02000000  10.6540742354     0x71826157                      // 04000000  113.5092978129 }; // - exponents in 8.24 format static const uint32_t etn[27] = {     0x00FFFFFF,                     // 00000001  0.9999999295     0x00FFFFFE,                     // 00000002  0.9999998590     0x00FFFFFB,                     // 00000004  0.9999997180     0x00FFFFF7,                     // 00000008  0.9999994359     0x00FFFFED,                     // 00000010  0.9999988718     0x00FFFFDA,                     // 00000020  0.9999977437     0x00FFFFB4,                     // 00000040  0.9999954873     0x00FFFF69,                     // 00000080  0.9999909747     0x00FFFED1,                     // 00000100  0.9999819495     0x00FFFDA2,                     // 00000200  0.9999638992     0x00FFFB45,                     // 00000400  0.9999277998     0x00FFF689,                     // 00000800  0.9998556048     0x00FFED13,                     // 00001000  0.9997112304     0x00FFDA28,                     // 00002000  0.9994225441     0x00FFB455,                     // 00004000  0.9988454217     0x00FF68C1,                     // 00008000  0.9976921765     0x00FED1DC,                     // 00010000  0.9953896791     0x00FDA51C,                     // 00020000  0.9908006133     0x00FB4FC4,                     // 00040000  0.9816858552     0x00F6B582,                     // 00080000  0.9637071184     0x00EDC157,                     // 00100000  0.9287314100     0x00DCCF8E,                     // 00200000  0.8625420320     0x00BE7564,                     // 00400000  0.7439787570     0x008DB277,                     // 00800000  0.5535043908     0x004E6E13,                     // 01000000  0.3063671106     0x00180743,                     // 02000000  0.0938608065     0x0002415D                      // 04000000  0.0088098510 }; uint32_t tpow(int32_t n) {     const uint32_t *et = etp;           // Assume + exponent     if(n < 0) n = -n, et = etn;         // Adjust for - exponent                                         //     uint32_t r = 1L << 24;              // Init result to 1.0 in 8.24 format                                         //     do {                                //         if(n & 1) r = mul824(r, *et);   // Multiply by exponent if lsb of n is 1         ++et;                           // Next exponent     } while(n >>= 1);                   // Next bit, loop until no more 1 bits                                         //     return r;                           // Return result }
×
×
  • Create New...