Jump to content
43oh

tripwire

Members
  • Content Count

    193
  • Joined

  • Last visited

  • Days Won

    14

Reputation Activity

  1. Like
    tripwire reacted to nemi in (Dual) Monitor auto windows desktop rotation   
    Hi Everyone,
     
    my first project with the launch pad is to automatically rotate my windows desktop orientation when I rotate my monitors.
     
    I have been working with dual monitors for a while but recently got a monoprice dual monitor stand that allows rotation.
    http://www.monoprice.com/products/product.asp?c_id=109&cp_id=10828&cs_id=1082808&p_id=5560&seq=1&format=2
     
    I then had the idea to implement my own hardware sensor to detect when they had been rotated to portrait (or even up-side-down).
     
    The circuit is simple and the pictures should explain everything.
     

     
    The hardware is the standard TI launchpad development board, together with Qty.4 tilt switches.
    I made a shield with two of the tilt switches on the launch pad (for mouing on the rear of monitor 1) and a mini pcb with the other two tilt switches (for the rear of monitor 2). Some wires a routed between the two.
     
    I'm using 4 pins as digital input pulled high. the tilt switches short to ground when closing the circuit. 2 tilt switches for each monitor encode the 4 possible positions (for each monitor).
     
    By placing the tilt switchers at 45 degrees to up-down and left-right there is good stability.
     
    Power, VCC and Qty.1 digital output (currently assigned to launch pad LEDs) are brought out to each PCB for any future expansion (e.g. ambient rear illumination etc.),
     
     
     
    The launchpad had version 0.01 of my general purpose IO code so that a windows program can read the status via com port serial command ("r").
     
    here is the launchpad code:
     
     

    // General purpose serial I/O (9600 baud) for launchpad // Peter R.H. 12/30/2010 onwards // heavily modified example 9600 uart code and other items // history // 1/1/2011 - "t" command not yet working. // original uart example notes //****************************************************************************** // MSP430G2xx1 Demo - Timer_A, Ultra-Low Pwr UART 9600 Echo, 32kHz ACLK // // Description: Use Timer_A CCR0 hardware output modes and SCCI data latch // to implement UART function @ 9600 baud. Software does not directly read and // write to RX and TX pins, instead proper use of output modes and SCCI data // latch are demonstrated. Use of these hardware features eliminates ISR // latency effects as hardware insures that output and input bit latching and // timing are perfectly synchronised with Timer_A regardless of other // software activity. In the Mainloop the UART function readies the UART to // receive one character and waits in LPM3 with all activity interrupt driven. // After a character has been received, the UART receive function forces exit // from LPM3 in the Mainloop which configures the port pins (P1 & P2) based // on the value of the received byte (i.e., if BIT0 is set, turn on P1.0). // ACLK = TACLK = LFXT1 = 32768Hz, MCLK = SMCLK = default DCO // //* An external watch crystal is required on XIN XOUT for ACLK *// // // MSP430G2xx1 // ----------------- // /|\| XIN|- // | | | 32kHz // --|RST XOUT|- // | | // | CCI0B/TXD/P1.1|--------> // | | 9600 8N1 // | CCI0A/RXD/P1.2|<-------- // // D. Dang // Texas Instruments Inc. // October 2010 // Built with CCS Version 4.2.0 and IAR Embedded Workbench Version: 5.10 //****************************************************************************** #include "msp430g2231.h" //------------------------------------------------------------------------------ // Hardware-related definitions //------------------------------------------------------------------------------ #define UART_TXD 0x02 // TXD on P1.1 (Timer0_A.OUT0) #define UART_RXD 0x04 // RXD on P1.2 (Timer0_A.CCI1A) //------------------------------------------------------------------------------ // Conditions for 9600 Baud SW UART, SMCLK = 1MHz //------------------------------------------------------------------------------ #define UART_TBIT_DIV_2 (1000000 / (9600 * 2)) #define UART_TBIT (1000000 / 9600) //------------------------------------------------------------------------------ // Global variables used for full-duplex UART communication //------------------------------------------------------------------------------ unsigned int txData; // UART internal variable for TX unsigned char rxBuffer; // Received UART character //------------------------------------------------------------------------------ // Function prototypes //------------------------------------------------------------------------------ void TimerA_UART_init(void); void TimerA_UART_tx(unsigned char byte); void TimerA_UART_print(char *string); //void ConfigureAdcTempSensor(void); // vars long temp; long IntDegF; long IntDegC; unsigned int TXByte; //------------------------------------------------------------------------------ // main() //------------------------------------------------------------------------------ void main(void) { WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer //for temperature reading TACTL = TASSEL_2 | MC_2; while (TAR < 30); // --- DCOCTL = 0x00; // Set DCOCLK to 1MHz BCSCTL1 = CALBC1_1MHZ; DCOCTL = CALDCO_1MHZ; P1OUT = 0x00; // Initialize all GPIO P1SEL = UART_TXD + UART_RXD; // Timer function for TXD/RXD pins // Set all pins but RXD, P1.3, P1.4, P1.5, P1.7 to output P1DIR = 0xFF & ~UART_RXD & ~0x08 & ~0x10 & ~0x20 & ~0x80; //unable to set P1.3 to pull low so set all the others to pull up (!) P1IN |= BIT4; //enables input P1REN |= BIT4; // enables resistor P1OUT |= BIT4; //resistor set to pull up P1IN |= BIT5; //enables input P1REN |= BIT5; // enables resistor P1OUT |= BIT5; //resistor set to pull up P1IN |= BIT7; //enables input P1REN |= BIT7; // enables resistor P1OUT |= BIT7; //resistor set to pull up P2OUT = 0x00; P2SEL = 0x00; P2DIR = 0xFF; __enable_interrupt(); TimerA_UART_init(); // Start Timer_A UART TimerA_UART_print("\r\r\rREADY.\r\n"); for (; { // Wait for incoming character __bis_SR_register(LPM0_bits); // Echo received character TimerA_UART_tx(rxBuffer); // Update board outputs according to received byte if (rxBuffer == '1') P1OUT |= 0x01; if (rxBuffer == '!') P1OUT &= ~0x01; if (rxBuffer == '6') P1OUT |= 0x40; if (rxBuffer == '^') P1OUT &= ~0x40; if (rxBuffer == 't') { ADC10CTL0 |= ENC + ADC10SC; // Sampling and conversion start __bis_SR_register(CPUOFF + GIE); // LPM0 with interrupts enabled temp = ADC10MEM; // oF = ((A10/1024)*1500mV)-923mV)*1/1.97mV = A10*761/1024 - 468 IntDegF = ((temp - 630) * 761) / 1024; // oC = ((A10/1024)*1500mV)-986mV)*1/3.55mV = A10*423/1024 - 278 IntDegC = ((temp - 673) * 423) / 1024; TXByte = (unsigned char)(IntDegC); TimerA_UART_tx(TXByte); TXByte = (unsigned char)(','); TimerA_UART_tx(TXByte); TXByte = (unsigned char)(IntDegF); TimerA_UART_tx(TXByte); } if (rxBuffer == 'r') { TimerA_UART_tx(';'); if ((8 & P1IN)) TimerA_UART_tx('1'); // if P1.3 set else TimerA_UART_tx('0'); if ((16 & P1IN)) TimerA_UART_tx('1'); // if P1.4 set else TimerA_UART_tx('0');rrr if ((32 & P1IN)) TimerA_UART_tx('1'); // if P1.5 set else TimerA_UART_tx('0'); if ((128 & P1IN)) TimerA_UART_tx('1'); // if P1.6 set else TimerA_UART_tx('0'); TimerA_UART_tx('.'); } } } //------------------------------------------------------------------------------ // Function configures Timer_A for full-duplex UART operation //------------------------------------------------------------------------------ void TimerA_UART_init(void) { TACCTL0 = OUT; // Set TXD Idle as Mark = '1' TACCTL1 = SCS + CM1 + CAP + CCIE; // Sync, Neg Edge, Capture, Int TACTL = TASSEL_2 + MC_2; // SMCLK, start in continuous mode } //------------------------------------------------------------------------------ // Outputs one byte using the Timer_A UART //------------------------------------------------------------------------------ void TimerA_UART_tx(unsigned char byte) { while (TACCTL0 & CCIE); // Ensure last char got TX'd TACCR0 = TAR; // Current state of TA counter TACCR0 += UART_TBIT; // One bit time till first bit TACCTL0 = OUTMOD0 + CCIE; // Set TXD on EQU0, Int txData = byte; // Load global variable txData |= 0x100; // Add mark stop bit to TXData txData <<= 1; // Add space start bit } //------------------------------------------------------------------------------ // Prints a string over using the Timer_A UART //------------------------------------------------------------------------------ void TimerA_UART_print(char *string) { while (*string) { TimerA_UART_tx(*string++); } } //------------------------------------------------------------------------------ // Timer_A UART - Transmit Interrupt Handler //------------------------------------------------------------------------------ #pragma vector = TIMERA0_VECTOR __interrupt void Timer_A0_ISR(void) { static unsigned char txBitCnt = 10; TACCR0 += UART_TBIT; // Add Offset to CCRx if (txBitCnt == 0) { // All bits TXed? TACCTL0 &= ~CCIE; // All bits TXed, disable interrupt txBitCnt = 10; // Re-load bit counter } else { if (txData & 0x01) { TACCTL0 &= ~OUTMOD2; // TX Mark '1' } else { TACCTL0 |= OUTMOD2; // TX Space '0' } txData >>= 1; txBitCnt--; } } //------------------------------------------------------------------------------ // Timer_A UART - Receive Interrupt Handler //------------------------------------------------------------------------------ #pragma vector = TIMERA1_VECTOR __interrupt void Timer_A1_ISR(void) { static unsigned char rxBitCnt = 8; static unsigned char rxData = 0; switch (__even_in_range(TAIV, TAIV_TAIFG)) { // Use calculated branching case TAIV_TACCR1: // TACCR1 CCIFG - UART RX TACCR1 += UART_TBIT; // Add Offset to CCRx if (TACCTL1 & CAP) { // Capture mode = start bit edge TACCTL1 &= ~CAP; // Switch capture to compare mode TACCR1 += UART_TBIT_DIV_2; // Point CCRx to middle of D0 } else { rxData >>= 1; if (TACCTL1 & SCCI) { // Get bit waiting in receive latch rxData |= 0x80; } rxBitCnt--; if (rxBitCnt == 0) { // All bits RXed? rxBuffer = rxData; // Store in global variable rxBitCnt = 8; // Re-load bit counter TACCTL1 |= CAP; // Switch compare to capture mode __bic_SR_register_on_exit(LPM0_bits); // Clear LPM0 bits from 0(SR) } } break; } } //------------------------------------------------------------------------------ // ADC10 interrupt service routine #pragma vector=ADC10_VECTOR __interrupt void ADC10_ISR (void) { __bic_SR_register_on_exit(CPUOFF); // Clear CPUOFF bit from 0(SR) }
     
    On the windows desktop side I am using the free software iRotate which provide hotkeys for roating the monitor layout.
    http://www.entechtaiwan.com/util/irotate.shtm
     
    I then coded an AutoIt program to poll the launchpad via serial and simualte pressign the correct irotate hot-keys.
    I have the irotate program and this autoit one in my windows startup folder.
     
    If you duplicate this project you may have to change this code if your tilt switches are different orientations and/or pins
     
    my autoit code is:

    ; Monitor rotate code ; Peter 1/1/2011 ; based upon serial code by "martin" ; http://www.autoitscript.com/forum/topic/45842-serial-port-com-port-udf/ ; http://www.mosaiccgl.co.uk/AutoItDownloads/confirm.php?get=COMMGv2.zip #include #include 'CommMG.au3';or if you save the commMg.dll in the @scripdir use #include @SciptDir & '\commmg.dll' #include #include #include #include ; keep track of new/old monitor states $m1old="" $m1="" $m2old="" $m2="" ; ^ = Control , + = shift , ! = ALT ; monitor 1 HotKeys $sup1="^!{UP}" $sdown1="^!{DOWN}" $sleft1="^!{LEFT}" $sright1="^!{RIGHT}" ; monitor 2 HotKeys $sup2="^+{UP}" $sdown2="^+{DOWN}" $sleft2="^+{LEFT}" $sright2="^+{RIGHT}" while ProcessExists("iRotate.exe")=False sleep(1000) ; allow irotate to start up WEnd sleep(2000) $serror="" _CommSetPort(5, $serror, 9600, 8, 0, 1, 0, 0, 0) while 1 sleep(200) _CommSendString("r",0) sleep(500) $sread = _CommGetLine(".",10,800) ;MsgBox(0,"responce",$sread) ;monitor 1 $m1=stringmid($sread,4,2) if $m1<>$m1old Then switch $m1 case "00" send($sup1,0) case "10" send($sright1,0) case "01" send($sleft1,0) case "11" send($sdown1,0) Endswitch EndIf $m1old=$m1 ;monitor 2 $m2=stringmid($sread,3,1)&stringmid($sread,6,1) if $m2<>$m2old Then switch $m2 case "00" send($sup2,0) case "10" send($sright2,0) case "01" send($sleft2,0) case "11" send($sdown2,0) Endswitch EndIf $m2old=$m2 sleep(1300) WEnd
     
    It uses the autoit serial routines from "Martin"
    http://www.autoitscript.com/forum/topic/45842-serial-port-com-port-udf/
     
    Enjoy!
     
    circuit pictures in the next post.


  2. Like
    tripwire reacted to pine in Article of TI SensorTag tear down   
    MAKE magazine article with photos of the board enclosed in the Sensor Tag:
     
    http://blog.makezine.com/2013/04/18/teardown-of-the-ti-sensortag/
  3. Like
    tripwire got a reaction from nemetila in accuracy of the 2553's built in temperature sensor?   
    It looks like you're not using the temperature sensor calibration values stored in info A on the 2553. I'm not sure if that's sufficient to cause the inaccuracy you're seeing, but it's worth a shot.
     
    The calibration values are mentioned in chapter 24 of the MSP430x2xx Family User's Guide and also on page 15 of the 2553 datasheet:
     
    The temperature sensor is calibrated using the internal voltage references. At VREF2_5 = 0 and 1, the
    12-bit conversion result at 30
  4. Like
    tripwire reacted to ElGuille in gscope   
    I needed to be able to watch signals from hundreds of Hz  to 10Khz . While reading the msp430 family manual found the Data Transfer Controller (DTC) that can be put to work with the ADC . 
     
    So the original launchscope by NJC streams data one sample at a time , and that is why it is so slow . So using the DTC we can actually get near the 200Ksps . 
     
    So I use an array of 200 integers (400 Bytes . I didn't want to leave the launchpad without ram, just 512B for the msp430g2553


  5. Like
    tripwire reacted to jazz in MSP430 USB Benchmark   
    I used stranded wire, nothing special. The most important thing is to have good magnifier. If you see what are you doing, than everything is much easier. I done some SMD p2p boards before (SOIC mostly), but this one was smallest work till now.
     
    I was thinking that poor USB connection (big non SMD resistors, no standard connector...) will have big impact on transfer rate, but it seems that full-speed USB transfer is not sensitive to this.
     

     

  6. Like
    tripwire got a reaction from Avalon in Timer Capture measurement of Period   
    Those capacitors aren't actually present on the board. The letters "DNP" alongside them mean "Do Not Populate". The oscillator circuit inside the MSP430 includes software-selectable load capacitors. You'll need to check that you've got the appropriate XCAP (or equivalent) bits set for the supplied crystal.
  7. Like
    tripwire reacted to Gareeeesh in Please help! I'm going mad trying to get this to work!   
    @Roadrunner & Tripwire - Thanks for all your help guys!. Mission accomplished!
    Here's another terrible video of my results!

  8. Like
    tripwire got a reaction from Gareeeesh in Please help! I'm going mad trying to get this to work!   
    It took me a while to figure that command line out, and it turns out to be the source of the problem. The command you're using is:
     
    set /p x="255" <nul >//./COM5
     
    Apart from the redirections, the command is setting the value of environment variable "x" to a value provided by the user, and showing "255" as a prompt. The input is redirected from nul so the command doesn't wait for user input. The output is redirected to the COM5 port. Crikey!
     
    It looks like a roundabout way of printing the string "255" to the COM5 port. What that means is the UART first receives the character '2', then '5', then another '5'. In other words three bytes instead of one.
     
    You'll need to find some way of sending raw data to the COM port instead of text. I'm not sure what to suggest for that.
     
    Anyway, the ASCII values of those characters are 50, 53 and 53. That's what's actually stored in the first three slots of the image array. When you inspect the array, however, they're shown as 2, 5, 5. That's the debugger helpfully displaying the values of character variables as characters rather than the ASCII value. If you click on the rows of that display you'll see the value in decimal, like so:

     
    Alternatively you can right click on the "image" array variable and "Add Watch Expression". Then you can right click the "image" variable in the watch window and set Number Format->Decimal. After that the debugger should show all the pixels as decimal values from 0-255.
  9. Like
    tripwire got a reaction from Gareeeesh in Sending Image as RGB Array to G2553   
    No, the array is arranged like this:
    GIMP array layout for a 4x4 pixel image. Pixel coordinates are shown as (X,Y). 0 1 2 3 4 5 ... R G B R G B R G B R G B R G B R G B R G B R G B R G B R G B R G B R G B R G B R G B R G B R G B 0 | \_/ \_/ | | \_/ \_/ | | | | | | | | | | | | | | | | | | \_ Null terminator | (1,0) (2,0) | | (1,1) (2,1) | | | | | | | | | | | | | \___________________/ \___________________/ \___________________/ \___________________/ | | | | Row 0 Row 1 Row 2 Row 3  
    The red, green and blue components of each pixel are stored as three consecutive elements of the array. The pixel at (X, Y) begins at index ((Y * WIDTH) + X) * 3) - that's the red component. Then green is at (((Y * WIDTH) + X) * 3) + 1) and blue is at (((Y * WIDTH) + X) * 3) + 2).
     
    For the example you quoted, that would mean:
    Pixel (7,2) red is at bytes_to_send[ (( 2 * gimp_image_width ) + 7) * 3] Pixel (7,2) green is at bytes_to_send[ ((( 2 * gimp_image_width ) + 7) * 3) + 1] Pixel (7,2) blue is at bytes_to_send[ ((( 2 * gimp_image_width ) + 7) * 3) + 2]  
    Hope that helps
  10. Like
    tripwire got a reaction from mike1994 in MSP430G2553 Timer1 interrupts trigger in debug, but don't when not in debug.   
    Ooops, I hadn't noticed that you're using TASSEL_1 (aka ACLK) as the timer source! ACLK is sourced from the LF crystal oscillator by default.
     
    Ike's post above includes the (quite bewildering ) lines:
    static int MAGIC_8MHz = ' '; ... BCSCTL3 = MAGIC_8MHz; Which are equivalent to:
     
    BCSCTL3 = LFXT1S_2; // ' ' == 0x20 == LFXT1S_2  
    That changes ACLK to be sourced from the VLO instead of the crystal oscillator. If that change fixes the problem, then the crystal is failing to start up correctly when you're running without the debugger attached.
     
    It's worth taking a look at this thread, which describes a similar issue and includes source for a test program to check the crystal oscillator.
  11. Like
    tripwire reacted to ILAMtitan in Vetinari's Clock   
    I figured you guys might be interested in some of my tinkering with the Launchpad.  Hopefully by putting a few of my projects up here it will also keep me accountable for finishing them.
     
    This is one a cobbled together a few months ago.  It's been up on the MCU projects page on E2E, so you might have already seen it: http://e2e.ti.com/group/microcontrollerprojects/m/msp430microcontrollerprojects/664670.aspx
     
     
    PROJECT OVERVIEW
    The Vetinari clock is from a book series known as Discworld, where Lord Verinari has a clock in his waiting room which has an irregular tick. The idea of the clock is to add a sense of unease and anxiety to anyone in the waiting room since their brain doesn't filter out the ticks like a normal clock. Here's a video to get a better idea of the result.  The tick is actually a lot louder in person.
     


     
    SOFTWARE DESIGN
    To accomplish this task on a 430, we create an array of possible time frames to tick the clock, and parse through it at 4Hz. The array is 32 entries long, so it equates to 32 seconds in the real world. By randomly setting 32 of the elements high, we create a timing sequence. A high element will generate a tick of the clock. This means a second on the clock can be as little as 250ms, or as long as 24 seconds, and still keep accurate time.  Check the attached software too see how it's all done; I did my best to comment it up.  main.c
     
    HARDWARE DESIGN
    The clock coil is driven via an alternating polarity pulse.  The easiest way to change a load's polarity with an MCU is using an h-bridge.
     

     
    The schematic shown is a simple implementation using two NPN and two PNP transistors.  I had the transistors and drive resistors laying around, so this part was easy to cobble together (along with the half used battery holder).  It would be easy to use a single IO pin per side of the bridge, but the transistors fit better onto the launchpad, as shown in the image.  To add the driving resistors in series, I cut a small gap in the traces, scrapped off the solder mask on either side to make pads, and put down a small SMA resistor.  It's not pretty, but it works.
     

     
    In the clock mechanism, there is a small control board with a crystal and epoxy glob IC that normally runs the clock.  I just ripped that out and directly attached the coil to the h-bridge.
     

     
    The resulting clock is actually more maddening than I expected in a quiet environment.  By using 3V rather than the 1.5V that the original movement used, the ticks are much more pronounced and do an excellent job of ruining a person's calm.
  12. Like
    tripwire reacted to yyrkoon in Where to find Books and Learning Resources   
    LariSan,
     
    You've done some youtube videos right ? You could make a short video of the book titles, and provide a link to the list on youtube, TI or you, and/or both Could have a blog page that is regularly updated. Point both links to one another to get more traffic, and makes posts via facebook, twitter, etc. Just like standard SEO stuff, but perhaps with no intention of generating ad income ? Could even do some ad generation maybe, but I think to TI this small amount would be trivial.
     
    Is this what you're asking ?
     
    EDIT:
     
    Also for what it is worth, you could do an additional post on the TI wiki, but from personal experiences, I've found the wiki to be lacking in that there is so much information there, it can be very hard to find what you need/want, even if you know what you're looking for, and that it exists. This for me also applies to TI's product pages. So much information, that generally things are hard to find.
     
    Truthfully, I think TI could use a dedicated web admin that knows how to organize information very well . . . Sorry if that is hurting anyone's feelings, but there is no way a customer should have to wade through more than 1-2 pages to find what they need. As it stands, sometimes you have to click through 5+ pages to find exactly what you're after. That is unacceptable.
  13. Like
    tripwire reacted to roadrunner84 in Timer Capture measurement of Period   
    First off, I don't own a fraunchpad and haven't ever looked into them.
    If you measure the crystal frequency with your oscilloscope you're influencing the frequency of the crystal. The MSP430G2 series accept a 12.5pF capacitance of the crystal, but can switch to 6pF at will. Most oscilloscopes (I've seen) have an input capacitance of about 50pF!
    The only way to measure your crystal without influencing it, is to set an output pin to output ACLK or SMCLK (some pins can do that) and set the DIVA_x and/or DIVS_x value to 0 (divide by 1). Now you can measure the observed frequency of your crystal (or crystal clock circuit) without altering its behaviour.
    For the MSP430G2 the pins used for the crystal oscillator are set to crystal oscillator function by default, but I'm not sure for the fraunchpad.
  14. Like
    tripwire got a reaction from Avalon in Timer Capture measurement of Period   
    I think you'd need the overflow interrupt to fire when TA0R rolls over. The CCR0 interrupt would only fire when the capture occurs.
     
    That means you'd need to be extra-careful of interrupt priorities, since the capture interrupt could happen at the same time as the TA0R interrupt. In that case the CCR0 interrupt would be processed first, and then the count would be off by 65535.
     
    BTW, I haven't tried any of this so I might be wrong
  15. Like
    tripwire got a reaction from roadrunner84 in Sending Image as RGB Array to G2553   
    Apologies for drifting way off topic, but 16-bit 5-6-5 format came into use a little later than that. It was used in the early days of the PC's transition to 3D hardware rendering, as well as on consoles a generation or two ago (eg PSP).
     
    C64 and Amiga used indexed colour screen modes, where each pixel stored an index into a colour look-up table (aka palette).
  16. Like
    tripwire reacted to roadrunner84 in Sending Image as RGB Array to G2553   
    @Gareeeesh: Not entirely correct, this is a ordinary array in any sense. Except for the very last entry. As it is a "string" it conforms to C string behaviours, this means there is a single '\0' character (null character) after the explicitly defined characters to denote the end-of-string (hence the '+ 1' in the array dimension). Since this is actually a binary string nistead of a text string, there might already be null character in the string. Printing this as text would thus stop et the very first occurence of the null character.
    But this string is not treated as a string, it is treated as a array of bytes (and unsigned chars happen to be just that; bytes). The writing of '\#' describes a byte value as a character, so '\0' becomes the byte value 0 and '\255' becomes the byte value 173. This is octal, so numbers are conted like 0,1,2,3,4,5,6,7,10,11,12, etc. If you switch your windows calculator to scientific/engineering mode you can switch to octal numbering to convert them to decimal (normal counting), but you can also take these numbers for granted. They'll be sent as 8-bit integer values over your serial line.
    Instead of separate arrays per line of image, there is a long string of pixels. After each line of image, the next line of image begins. Since each pixel is 3 bytes long (R,G, ech pixel is 3 bytes further in the array than the pixel before.
    The first pixel is at position [0], the second at position [3], the third at position [6]. In a general sense pixel N is at position [N*GIMP_IMAGE_BYTES_PER_PIXEL].
    Since the second line starts after the first line, and we know the (first) line is a known number of pixels wide, we can calculate the position of the first pixel of the second line by determining the number of pixels in a line and use that as the number of pixels. In this case, the first pixel of the second line (lines are 16 pixels wide) is the 17th pixel or pixel index [16]. In a more general sense, the first pixel of any row M is [M*GIMP_IMAGE_BYTES_PER_PIXEL*GIMP_IMAGE_WIDTH].
    If we combine these two formulas. Then the Nth pixel of the Mth line becomes [N*GIMP_IMAGE_BYTES_PER_PIXEL + M*GIMP_IMAGE_BYTES_PER_PIXEL*GIMP_IMAGE_WIDTH], or a bit simpler [(N + (M*GIMP_IMAGE_WIDTH))*M*GIMP_IMAGE_BYTES_PER_PIXEL].
    If you want to know the value of pixel (7,2) as tripwire used, the value becomes [(7 + (2*GIMP_IMAGE_WIDTH))*M*GIMP_IMAGE_BYTES_PER_PIXEL]. You see the formula is identical (with tripwire hardcoding 3 for GIMP_IMAGE_BYTES_PER_PIXEL).
  17. Like
    tripwire reacted to pabigot in How to properly config ADC sampling rate?   
    Is that 25E1 Hz, 250.Hz, or 250.000Hz? The accuracy will depend the trigger source; if your trigger is from an internal clock you'll need to understand its accuracy characteristics. A general approach is to trigger an A2D using a timer output, then use an interrupt or DMA on completion of the A2D conversion to process the data. I believe timer-based ADC conversions is a standard example in the MCU example programs available for whatever MCU you're using. 
    As RR84 suggests also check the data sheet for your MCU to determine whether the range of ADC sampling rates you need can be supported.
  18. Like
    tripwire reacted to kff2 in Using the internal temperature sensor   
    One gram of water is actually A LOT of matter: one cubic centimeter to be precise. By comparison, the entire MSP430 silicone layer is probably on the order of 2 mm x 2 mm x a few microns, which could be 1 / 100,000th of a gram. The power dissipates through the plastic of course, but you could still have significant temperature gradients as you get closer to the die (consider our planet -- molten rock inside, but relatively cold on the outside).
     
    The reason I think heat is responsible for inaccurate temperature readings is that I tried oPossum's code and noticed that temperatures are fairly accurate when I first turn on the launchpad, but then go up 10-20 degrees over time. It's hard to imagine anything else causing this shift.
  19. Like
    tripwire reacted to jpnorair in STM32L vs. MSP430F5: What's left for MSP430?   
    Re the AVR stuff: In practice, MSP430 is lower-power than AVR.  MSP430 generally uses lower voltage, and it is quite a bit more code-efficient and IPC-efficient than AVR.... and AVR is quite a bit better in these respects than is PIC.  People maybe think that I don't like the MSP430, but that is incorrect.  I think it's great for a lot of things.  However, I think the AVR is a piece of outdated crap.  The G-series MSP makes AVR worthless to me.
     
    Anyway, more quantitative argument now:
     
    I am also most interested in the power-down mode that preserves a timer and the contents of RAM.  I think this is the mode that should be compared between micros, and for this the 328P is listed at about 1uA.  In any case, what can matter even more is the active mode, and the speed of entry from sleep into active mode.
     
    A common low-duty application has a timer and 1/1000 duty.  In other words, the MCU is active for 1 millisecond out of 1s.  If sleep is 1uA and active is 1mA, and duty is 1/1000, then average is 2uA.  This is actually the reason why STM32L works better for me than MSP430F5 does.  The sleep current is about the same, but during active mode STM32L uses 1mA to run the code in X ms, whereas MSP is using about 3mA to run the code in X ms.  AVR in active mode seems to need about double the current -- and often double the voltage -- to meet the runtime efficiency of the MSP430.  
     
    To give some real numbers, the Atmega 328P needs to run at about 20 MHz to match the STM32L doing 4.2 MHz.  The voltage here is ~1.8V for the STM32L and ~5V for the 328P, and the current is respectively 1mA vs. 20mA (est).  So, the STM32L is using less than 1/50 the power of the 328P to run the same code.  If STM32L needs 2uA in sleep, that extra 1uA is nothing compared to the savings in active mode, and not to mention the ability to run on two alkaline batteries without an SMPS.  The extra cost in batteries or SMPS outweighs the cost advantage of using the 328P in the first place.
  20. Like
    tripwire reacted to pabigot in STM32L vs. MSP430F5: What's left for MSP430?   
    To be clear, LPM4 retains registers and RAM as well.  It just doesn't meet your other requirement of independent timed wakeup.  The MSP430G2553 is still pretty capable and will do 0.4uA in LPM3 and below 0.1uA in LPM4, which beats anything Energy Micro has at least until their M0 chips come out later this year.
     
    Based on the data sheets, the FR5969 does LPM3 at 0.7uA with 7us wakeup.  At LPM3.5 you use 0.5uA and get RTC timed wakeup but spend 250us for wakeup, plus a little time to reprogram the peripheral registers.  Active mode is 100uA/MHz.
     
    The EFM32 (TG230) needs 1uA to keep the RTC running (EM2), but wakes in 2us, with active mode at 150uA/MHz.  Lower power at EM3 and EM4, but you lose the clock so would have to compare with LPM4.5.
     
    I don't agree it's immediately obvious the MSP430 warrants a "fail".  Whether one mode FAR^3 exceeds another in energy use really requires analysis in the context of specific use cases.
  21. Like
    tripwire reacted to jpnorair in I2C vs. SPI   
    SPI is generally easier and better IF you have a system architecture that is Master/Slave.  I2C generally works in Master/Slave mode, as well, but it can also work as a Master/Master mode.  I2C is a good substitute for UART.
     
    Also, a myth with I2C is that it is only 100, 400, 1000 kbps.  These are just standardized limits to improve interoperability. I2C is clocked, so if you are generating 348kbps (or whatever), it isn't a problem for 400kbps rated devices.
     
    Anyway, I2C is a good substitute for UART.  If you want something similar to UART but better, that is the best usage of I2C.
  22. Like
    tripwire got a reaction from roadrunner84 in Poor treatment from FedEx   
    As far as I know, problems with moisture ingress only apply to reflow soldering. In a reflow oven the whole component is brought up to soldering temperature. To avoid damage to the component body the moisture level and oven temperature profile need to be carefully controlled.
     
    When you're hand soldering there might be some heat conducted from the leads to the case, but not enough to bring the whole component up to about 230 degrees C.
  23. Like
    tripwire got a reaction from Fred in Poor treatment from FedEx   
    As far as I know, problems with moisture ingress only apply to reflow soldering. In a reflow oven the whole component is brought up to soldering temperature. To avoid damage to the component body the moisture level and oven temperature profile need to be carefully controlled.
     
    When you're hand soldering there might be some heat conducted from the leads to the case, but not enough to bring the whole component up to about 230 degrees C.
  24. Like
    tripwire reacted to mechg in PowerScope   
    43oh Store link   I found myself wanting a dedicated power monitor to use while developing battery-powered application circuits, so I built one using the MSP430G2402.    http://code.google.com/p/powerscope/   This device has already helped me identify and eliminate about 40% of the power usage of a project in-progress.   Right now, I just have the code as a zip file on the download tab, but if anyone wants to develop additional features, I can check the code into Subversion and create some branches.    The board can be ordered for about $12 (for 3 boards) by uploading the Eagle .brd file to http://www.oshpark.com I don't make any money from oshpark.   Greg Glenn
    http://gravitastech.weebly.com/
  25. Like
    tripwire reacted to yyrkoon in TI deals is back   
    Now if they would actually fix their webpage to actually allow you to scroll to the bottom, or just take that useless bit out.
×
×
  • Create New...