Jump to content
43oh

tingo

Members
  • Content Count

    157
  • Joined

  • Last visited

Reputation Activity

  1. Like
    tingo reacted to larsie in Connecting to MSP430G2553 serial using Ubuntu   
    I've adapted some serial code from this forum to RX and TX over serial. It works on Windows, but I can't get it to work on Ubuntu. I have probably done something really silly, as I'm not used to using serial on Linux. I've tried with minicom and picocom. I can see the stuff being sent from the device, but the device isn't picking up what I'm sending to it. Any ideas? Permissions? CR/LF? HW-CTRL?
     
    Edit: I found the reason. I should have been looking for /r and not /n... Works now.
     

    // Based on Nathan Zimmerman's code at http://www.43oh.com/forum/viewtopic.php?f=10&p=15345#p15345 // Adapted and added to by Lars Roland // For USCI (MSP430G2553 etc) //#include #include #include #include "uart.h" #define interrupt(x) void __attribute__((interrupt (x))) unsigned char rx_buffer[102]; int len; void uartInit(void) { BCSCTL1 = CALBC1_1MHZ; // Set DCO to 1MHz DCOCTL = CALDCO_1MHZ; len = 0; ////////////////USCI setup//////////////// P1SEL = BIT1 + BIT2; // Set P1.1 to RXD and P1.2 to TXD P1SEL2 = BIT1 + BIT2; // //P1DIR |= BIT0 | BIT6; // Set P1.0 and P1.6 as output //P1OUT |= BIT0; // Toggle P1.0 //P1OUT |= BIT6; // Toggle P1.6 UCA0CTL1 |= UCSSEL_2; // Have USCI use SMCLK AKA 1MHz main CLK UCA0BR0 = 104; // Baud: 9600, N= CLK/Baud, N= 10^6 / 9600 UCA0BR1 = 0; // Set upper half of baud select to 0 UCA0MCTL = UCBRS_1; // Modulation UCBRSx = 1 UCA0CTL1 &= ~UCSWRST; // Start USCI IE2 |= UCA0RXIE; //Enable RX interrupt _BIS_SR(GIE); // Interrupt } void putchar(unsigned char c) { UCA0TXBUF = c; // write c to TX buffer while(!(IFG2&UCA0TXIFG)); //P1OUT ^= BIT6; // Toggle P1.6 } void putstring(unsigned char *tx_message) { unsigned int i = 0; while (tx_message[i] != '\0') { putchar(tx_message[i++]); if (i > 100) { break; } } } int getString(unsigned char *message) { for (int i = 0; i < len; i++) { message[i] = rx_buffer[i]; } int length = len; len = 0; return length; } interrupt(USCIAB0RX_VECTOR) USCI0RX_ISR(void) { P1OUT ^= BIT0; // Toggle P1.0 unsigned char ch = UCA0RXBUF; UCB0TXBUF = ch; if (ch == '\r') { // Ignore } else if (ch == '\n') { rx_buffer[len++] = '\r'; rx_buffer[len++] = '\n'; rx_buffer[len++] = '\0'; __bic_SR_register_on_exit(CPUOFF); } else if (len < 100) { rx_buffer[len++] = ch; } }
  2. Like
    tingo reacted to bulareanuadrian in Road Sign Recognition Car   
    Hi,
     
    My name is Bulareanu Adrian Costin and I present you a special project of mine.
    But i can't attach off-site URLs. Until I'll put videos if you are curios please check the channel bulareanuadrian on youtube.
     
    Thank you,
    Adrian Costin Bulareanu
  3. Like
    tingo reacted to greeeg in Epaper desk calendar   
    Hi all,
     
    So basically instead of buying another one of those desk calendars that you tear of each day as it goes by I decided to make use of an epaper display from Sparkfun (that up until last week had been collecting dust) to create a digital daily calendar.
     
    The screen fits 20 16 segment digits on 2 lines. This gives enough room to display the current day of the week, and date. It is powered by a Li-ion cell from an old laptop battery, rated at 2.4Ah. (My estimates put the battery dying in about 200 years, as this draws ~20mAh for ~6 seconds every 24 hours )

     
    This was originally a launchpad project but I ported it to a F2013 board by changing one line, Shows how universal the code is
    The current hardware consists of a F2013 board that I got free from TI during one of their promo's. The board is soldered directly to the back of the epaper breakout board.

     
    The code is attached. The 2kb of flash available on the MSP430F2013 didn't give much wriggle room. currently the code compiles with about 64 bytes of flash free.
    Due to the sparkfun breakout board not breaking out the enable pin for the on board boost circuit I found to achieve reasonable low power consumption I had to connect the power Pins of the display to IO pins on the MSP430F2013

    main.c
  4. Like
    tingo reacted to oPossum in Digital Picture Frame Thermometer   
    A digital picture frame is used as a thermometer. Pictures representing a range of temperature are displayed by simulating the press of the next or previous buttons on the picture frame. This makes the project very simple by avoiding having to drive the LCD directly with the microcontroller. The high resolution backlit display is much more readable than the usual reflective monochrome LCD thermometer and the pictures can be as simple or fancy as you want.
     
    A Maxim DS1820, DS18S20, DS18B20 or DS1822 temperature sensor can be used. The code will adapt to any of these models. The DS18B20 is recommend.
     
    The main code is written in C and uses assembly libraries for speed and precision timing. All the assembly code has been posted previously: Dallas/Maxim one wire library, Fast itoa() for CCS, and Compact serial tx
     
    Typical wiring

     
    Simple text display on picture frame. The text color changes with temperature (blue -> green -> yellow -> red)

     
    Serial output shows Deg C, Deg F, Displayed temperature, and up/down actions.

     
    Excerpt from main.c showing how the temperature sensor is read and the display is updated when necessary. Hysteresis is used to ensure a stable display.

    do { // puth(owrst()); // Reset puth(owwb(0x33)); // Read ROM puts("\r\n"); // } while(!read_block(id, 9)); // Read ID and serial show_block(id, 8); // // for(; { // print_temp(tc); // Show Deg C on terminal print_temp(tf); // Show Deg F on terminal itoa(display, s); puts(s); // Show displayed temperature on terminal // delta = tf - (display << 4); // Difference between measured and displayed // if(delta > hyst) { // - Above displayed ++display; // Increment displayed pb(1 << up_pin); // Push up button puts(" Up"); // } else if(-delta > hyst) { // - Below displayed --display; // Decrement displayed pb(1 << down_pin); // Push down button puts(" Down"); // } // puts("\r\n"); // // tc = tf = error_temp << 4; // Default to error temperature if(!owrst()) continue; // Convert if(owww(0x44CC) != 0x44CC) continue; // delay_ms(800); // Wait for conversion to complete if(!owrst()) continue; // Read temperature if(owww(0xBECC) != 0xBECC) continue; // if(read_block(b, 9)) continue; // // tc = b[1]; tc <<= 8; tc |= b[0]; // All if(id[0] == 0x10) { // DS1820 and DS18S20 only tc <<= 3; // Convert 1/2 C resolution to 1/16 C resolution if(b[7] == 16) { // DS18S20 12 bit only (divisor of DS1820 is not fixed at 16) tc &= 0xFFF0; tc = tc + 12 - b[6]; // Update with residual count for 1/16 C resolution } // } // tf = ((tc + (tc << 3)) + 2562 ) / 5; // Convert deg C to deg F }
     
    Complete code
    dpft.zip
  5. Like
    tingo reacted to oPossum in Fraunchpad poly synth   
    16 voices of 16 bit x 257 interpolated wavetable - derived from this code for the Launchpad.
    PWM output, but could easily be adapted to use IIC DAC.
     
    This is preliminary and eXperimental. The CPU core seems to be running slower than it should and I don't yet know why. Right now it is limited to 9 voices. The 9600 bps UART on the dev board was used for this demo, but standard MIDI can also be used - just change the bit rate divisor and wire up the usual opto circuit for MIDI.
     
    This is part of a larger project I am working on.
     


     

    //main.c #include "msp430fr5739.h" void synth_init(void); void set_note(int, int, int); static int assign[16]; void note_on(int n, int v) { int i; for(i = 0; i < 16; ++i) { if(assign[i] == -1) { assign[i] = n; set_note(i, n, v); break; } } } void note_off(int n) { int i; for(i = 0; i < 16; ++i) { if(assign[i] == n) { assign[i] = -1; set_note(i, -1, 0); break; } } } void midi_ex(unsigned a, unsigned b, unsigned c) { ++PJOUT; switch(a & 0xF0) { case 0x90: // Note on if(c) { note_on(b, c); break; } // fall thru case 0x80: // Note off note_off(; break; /* case 0xA0: // Note aftertouch break; case 0xB0: // Controller break; case 0xC0: // Program change break; case 0xD0: // Channel aftertouch break; case 0xE0: // Pitch bend break; case 0xF0: // Sysex / Meta break; */ } } void midi(unsigned c) { static const unsigned ps[8] = { 2, 2, 2, 2, 1, 1, 2, 4 }; static unsigned state = 0; static unsigned rs = 0; static unsigned d1 = 0; if(c & 0x80) { // First octect of sequence rs = c; state = ps[(rs >> 4) & 7]; } else { switch(state) { case 0: // Discard break; case 1: // Second and final octet midi_ex(rs, c, 0); break; case 2: // Second octet of three d1 = c; ++state; break; case 3: // Third and final octet midi_ex(rs, d1, c); state = 2; break; //case 4: // Sysex data // break; } } } void main(void) { unsigned n; WDTCTL = WDTPW + WDTHOLD; CSCTL0 = 0xA500; // Unlock clock registers CSCTL1 = DCORSEL | DCOFSEL1 | DCOFSEL0; // 24 MHz CSCTL2 = 0x0333; // Use DCO clock for ACLK, SMCLK and MCLK CSCTL3 = 0x0000; // Set all clock dividers to 1 //CSCTL4 = //CSCTL5 = P1DIR = 0x01; // PWM audio out P1REN = 0x00; // P1OUT = 0x00; // P1SEL0 = 0x01; // Enable Timer A output P1SEL1 = 0x00; // P2DIR = 0x00; // P2REN = 0x00; // P2OUT = 0x00; // P2SEL0 = 0x00; // P2SEL1 = 0x03; // Enable UART UCA0 P3DIR = 0x10; // P3REN = 0x00; // P3OUT = 0x00; // P3SEL0 = 0x10; // SMCLK output P3SEL1 = 0x10; // SMCLK output P4DIR = 0x00; // P4REN = 0x00; // P4OUT = 0x00; // P4SEL0 = 0x00; // P4SEL1 = 0x00; // PJDIR = 0x0F; // 4 LEDs PJREN = 0x00; // PJOUT = 0x0F; // PJSEL0 = 0x00; // PJSEL1 = 0x00; // UCA0CTLW0 = 0x0080; // UCA0BRW = 24000000 / 9600; // Fraunchpad UART //UCA0BRW = 24000000 / 31250; // Standard MIDI bit rate synth_init(); //set_note(0, 69, 700); // 440 Hz test for(n = 0; n < 16; ++n) assign[n] = -1; for(; { if(UCA0IFG & 1) { UCA0IFG &= ~1; n = UCA0RXBUF; midi(n); } } }
     

    ;synth.asm .cdecls C, LIST, "msp430fr5739.h" smplrt .equ 32000 ; Sample rate .text .global set_tick .global get_tick .global synth_init .global set_note .bss tick, 2 .bss pwm_out, 2 .bss phase_inc, 6 * 16 ; Phase increment LSW/MSW (from note table) ; Level .bss phase_acc, 4 * 16 ; Phase accumulator LSW/MSW set_tick mov R12, &tick reta get_tick mov &tick, R12 reta synth_init mov #0x0210, &TA0CTL ; Timer A config: SMCLK, count up mov #750, &TA0CCR0 ; Setup Timer A period for 32000 sps mov #375, &TA0CCR1 ; Setup Timer A compare mov #0x00E0, &TA0CCTL1 ; Setup Timer A reset/set output mode ; mov #phase_inc, R12 ; Clear all phase inc and accum mov #5 * 16, R14 ; Word count clr 0(R12) ; Clear word incd R12 ; Next word dec R14 ; Dec word count jne $ - 8 ; Loop until all words done... ; eint ; Enable interupts bis #0x0010, &TA0CCTL0 ; Enable PWM interupt ; reta ; ; synth_isr ; mov &pwm_out, &TA0CCR1 ; Output sample ; push R4 ; Wavetable pointer push R5 ; Phase increment / level pointer push R6 ; Phase accumulator pointer push R7 ; Voice count push R8 ; Wave sample pointer / next sample push R9 ; Wave sample push R10 ; Voice mix accumulator MSW push R11 ; Voice mix accumulator LSW ; mov #sine, R4 ; Get wavetable pointer mov #phase_inc, R5 ; Setup phase increment pointer mov #phase_acc, R6 ; Setup phase accumulator pointer mov #16, R7 ; Setup voice count mov #9, R7 ; clr R10 ; Clear voice mix clr R11 ; voice_loop ; mov @R6+, &MPYS32L ; Get phase acc LSW (fraction) to multiplier clr &MPYS32H ; mov @R6+, R8 ; Get phase acc MSW (wave table index) mov.b R8, R8 ; Clear MSB (use mask for smaller / larger tables) add R4, R8 ; Add wavetable pointer mov @R8+, R9 ; Get wave sample mov @R8, R8 ; Get next wave sample sub R9, R8 ; Calc delta mov R8, &OP2L ; Multiply by delta subc R8, R8 ; Sign extend delta mov R8, &OP2H ; add @R5+, -4(R6) ; Update phase acc addc @R5+, -2(R6) ; add &RES1, R9 ; Add interpolation to sample mov R9, &MPYS ; Multiply by voice level mov @R5+, &OP2L ; add &RES0, R11 ; Update mix addc &RES1, R10 ; dec R7 ; Dec voice count jne voice_loop ; Next voice... ; add #375, R10 ; Bias to center of PWM range mov R10, &pwm_out ; ; dec &tick ; jc $ + 6 ; clr &tick ; ; pop R11 ; pop R10 ; pop R9 ; pop R8 ; pop R7 ; pop R6 ; pop R5 ; pop R4 ; reti ; ; set_note ; push R14 ; Save level mov R12, R14 ; Voice * 6 add R14, R12 ; (+1 = *2) add R14, R12 ; (+1 = *3) rla R12 ; (*2 = *6) add #phase_inc, R12 ; Add phase inc pointer cmp #128, R13 ; Out of range note values are note off jhs note_off ; clr R14 ; Clear octave count tst_note ; cmp #116, R13 ; Within note table? jge get_pi ; Yes... inc R14 ; Inc octave count add #12, R13 ; Add octave to note jmp tst_note ; Check again... get_pi ; Get phase increment sub #116, R13 ; Adjust for first note in table rla R13 ; MIDI note * 4 rla R13 ; add #notes, R13 ; Add note table pointer mov @R13+, R15 ; Get LSW mov @R13, R13 ; Get MSW tst R14 ; Shifting required? jeq set_phase ; No... shift_phase ; rra R13 ; Shift phase inc rrc R15 ; dec R14 ; Dec octave count jne shift_phase ; Repeat until zero... set_phase ; mov R15, 0(R12) ; Set phase inc mov R13, 2(R12) ; pop 4(R12) ; Set voice level reta ; Return ; note_off ; incd SP ; Discard level clr 0(R12) ; Clear phase inc clr 2(R12) ; .if 0 ; Note: Abrupt return to zero causes poping clr 4(R12) ; Clear level add #phase_acc - phase_inc, R12 ; Phase accum pointer clr 0(R12) ; Clear phase accum clr 2(R12) ; .endif ; reta ; Return ; ; notes ; MIDI Note Frequency .if smplrt == 32000 ; 32000 sps .long 3483828 ; 116 G#8 6644.87457275391 .long 3690988 ; 117 A8 7040.00091552734 .long 3910465 ; 118 A#8 7458.62007141113 .long 4142993 ; 119 B8 7902.13203430176 .long 4389349 ; 120 C9 8372.01881408691 .long 4650353 ; 121 C#9 8869.84443664551 .long 4926877 ; 122 D9 9397.27210998535 .long 5219845 ; 123 D#9 9956.06422424316 .long 5530233 ; 124 E9 10548.0823516846 .long 5859077 ; 125 F9 11175.3025054932 .long 6207476 ; 126 F#9 11839.8208618164 .long 6576592 ; 127 G9 12543.8537597656 .endif ; ; .if smplrt == 48000 ; 48000 sps .long 2322552 ; 116 G#8 6644.87457275391 .long 2460658 ; 117 A8 7039.99900817871 .long 2606977 ; 118 A#8 7458.62102508545 .long 2761996 ; 119 B8 7902.13394165039 .long 2926232 ; 120 C9 8372.01690673828 .long 3100235 ; 121 C#9 8869.84348297119 .long 3284585 ; 122 D9 9397.27306365967 .long 3479896 ; 123 D#9 9956.06231689453 .long 3686822 ; 124 E9 10548.0823516846 .long 3906052 ; 125 F9 11175.3044128418 .long 4138318 ; 126 F#9 11839.8227691650 .long 4384395 ; 127 G9 12543.8547134399 .endif ; sine .int 0 .int 804 .int 1608 .int 2410 .int 3212 .int 4011 .int 4808 .int 5602 .int 6393 .int 7179 .int 7962 .int 8739 .int 9512 .int 10278 .int 11039 .int 11793 .int 12539 .int 13279 .int 14010 .int 14732 .int 15446 .int 16151 .int 16846 .int 17530 .int 18204 .int 18868 .int 19519 .int 20159 .int 20787 .int 21403 .int 22005 .int 22594 .int 23170 .int 23731 .int 24279 .int 24811 .int 25329 .int 25832 .int 26319 .int 26790 .int 27245 .int 27683 .int 28105 .int 28510 .int 28898 .int 29268 .int 29621 .int 29956 .int 30273 .int 30571 .int 30852 .int 31113 .int 31356 .int 31580 .int 31785 .int 31971 .int 32137 .int 32285 .int 32412 .int 32521 .int 32609 .int 32678 .int 32728 .int 32757 .int 32767 .int 32757 .int 32728 .int 32678 .int 32609 .int 32521 .int 32412 .int 32285 .int 32137 .int 31971 .int 31785 .int 31580 .int 31356 .int 31113 .int 30852 .int 30571 .int 30273 .int 29956 .int 29621 .int 29268 .int 28898 .int 28510 .int 28105 .int 27683 .int 27245 .int 26790 .int 26319 .int 25832 .int 25329 .int 24811 .int 24279 .int 23731 .int 23170 .int 22594 .int 22005 .int 21403 .int 20787 .int 20159 .int 19519 .int 18868 .int 18204 .int 17530 .int 16846 .int 16151 .int 15446 .int 14732 .int 14010 .int 13279 .int 12539 .int 11793 .int 11039 .int 10278 .int 9512 .int 8739 .int 7962 .int 7179 .int 6393 .int 5602 .int 4808 .int 4011 .int 3212 .int 2410 .int 1608 .int 804 .int 0 .int -804 .int -1608 .int -2410 .int -3212 .int -4011 .int -4808 .int -5602 .int -6393 .int -7179 .int -7962 .int -8739 .int -9512 .int -10278 .int -11039 .int -11793 .int -12539 .int -13279 .int -14010 .int -14732 .int -15446 .int -16151 .int -16846 .int -17530 .int -18204 .int -18868 .int -19519 .int -20159 .int -20787 .int -21403 .int -22005 .int -22594 .int -23170 .int -23731 .int -24279 .int -24811 .int -25329 .int -25832 .int -26319 .int -26790 .int -27245 .int -27683 .int -28105 .int -28510 .int -28898 .int -29268 .int -29621 .int -29956 .int -30273 .int -30571 .int -30852 .int -31113 .int -31356 .int -31580 .int -31785 .int -31971 .int -32137 .int -32285 .int -32412 .int -32521 .int -32609 .int -32678 .int -32728 .int -32757 .int -32767 .int -32757 .int -32728 .int -32678 .int -32609 .int -32521 .int -32412 .int -32285 .int -32137 .int -31971 .int -31785 .int -31580 .int -31356 .int -31113 .int -30852 .int -30571 .int -30273 .int -29956 .int -29621 .int -29268 .int -28898 .int -28510 .int -28105 .int -27683 .int -27245 .int -26790 .int -26319 .int -25832 .int -25329 .int -24811 .int -24279 .int -23731 .int -23170 .int -22594 .int -22005 .int -21403 .int -20787 .int -20159 .int -19519 .int -18868 .int -18204 .int -17530 .int -16846 .int -16151 .int -15446 .int -14732 .int -14010 .int -13279 .int -12539 .int -11793 .int -11039 .int -10278 .int -9512 .int -8739 .int -7962 .int -7179 .int -6393 .int -5602 .int -4808 .int -4011 .int -3212 .int -2410 .int -1608 .int -804 .int 0 ; Interrupt Vectors .sect ".int53" ; TA0CCR0 CCIFG0 .short synth_isr ; ; .end ;
  6. Like
    tingo reacted to TopHatHacker in MSP430 RRoD Belt Buckle   
    So I was at work, minding my own business .. not actually working but hanging out in the IRC channel. Shapr gave me a pretty good idea and I decided to work up a prototype.. though I probably took the idea a little further than I needed to.
     
    Anything worth doing is worth overdoing! ha
     
    Well my 'whim' project is a prototype for my MSP430 Red Ring of Death Belt Buckle.. The LED's on an xbox 360 daughter board clip into the front with a small light diffuser that I reused with the new board, it clipped right on.
    (the old board)
     
    the front button does work and thats what i'll use to go through the different programs and turn it off
     
    and heres a quick vid of the new board


     
    I'll be working up a 'finished product' that will just clip into an xbox360 front panel... it won't go into a working xbox but could be used as a wall decoration or something. I figure with the board, msp430, and the button each device will cost me around $10-15. i'm recycling the LED's from old boards, but that shouldn't push up the cost too much. I'll be putting in a run for these boards soon so if anyone is interested, let me know and I can work up a few more.
     
    As I get the Eagle PCB's finished I'll post them up here and on my website
    TopHatHacker.com
  7. Like
    tingo reacted to steve_m in Launchpad e-paper clock with Motorola F3 display   
    Hi,
     
    I wanted to play with the low-power abilities of the MSP430, so I put together a simple clock using the e-paper display from a Motorola F3.
    See the full documentation in my wiki, as well as the
    I recorded. The code can be found on github. 


     
    Steve
  8. Like
    tingo reacted to RobG in MSP430 LaunchPad, 74HC595, Four 7 Segment Displays   
    ****************
    For the latest, see this post
    ****************
     
    In this example, I have replaced LEDs with four 7 segment displays.
     
    Note: I am using HC series, not HCT. LaunchPad provides 3.6V, HCT needs 5V.
     


     

    #include unsigned int counter = 0; // Counter variable unsigned int digitCounter = 0; // Digit counter unsigned char digit = 0; // Single digit to be displayed unsigned char bcd7digit[10] = {0x3F,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,0x7F,0x6F}; // BCD to 7 digit map unsigned char digitSelector[4] = {0x01, 0x02, 0x04, 0x08}; // Digit selector map void main(void) { WDTCTL = WDTPW + WDTHOLD; // Stop WDT P1OUT |= 0x01; // Port P1.0 will be used to latch P1DIR |= 0x01; USICTL0 |= USIPE6 + USIPE5 + USIMST + USIOE; // Out & clk enable, SPI Master USICTL1 |= USICKPH + USIIE; // Counter interrupt, flag remains set USICKCTL = USIDIV_7 + USISSEL_2; // /128 SMCLK USICTL0 &= ~USISWRST; // USI released for operation USICNT = USI16B; // Enable 16 bit CCTL0 = CCIE; // CCR0 interrupt enabled CCR0 = 500; // TACTL = TASSEL_2 + MC_1 + ID_3; // SMCLK, upmode _bis_SR_register(LPM0_bits + GIE); // Enter LPM0 w/ interrupt } // Timer A0 interrupt service routine #pragma vector = TIMERA0_VECTOR __interrupt void Timer_A (void) { digitCounter++; // Increase digit counter digitCounter &= 0x03; // Mask, counter range is 0-3 digit = counter>>(4 * digitCounter); // Shift digits right digit &= 0x0F; // Mask, we need first digit only USISRL = bcd7digit[digit]; // Get segments from the map USISRH = digitSelector[digitCounter]; // if(digitCounter == 0) { counter = _bcd_add_short(counter, 0x01);// Decimally increase counter's when on first digit } USICNT |= 16; // Start USI } // USI interrupt service routine #pragma vector = USI_VECTOR __interrupt void USI_TXRX (void) { USICTL1 &= ~USIIFG; // Clear pending flag P1OUT &= ~0x01; // Latch data P1OUT |= 0x01; }

  9. Like
    tingo reacted to Maris in Interfacing Launchpad to Digital Caliper   
    Hello there,
    I'm new here and this is my first Launchpad project. May I apply for project of the moth contest? (BTW this is cool idea as those kind of things always help to find motivation to describe what you did not just stop when you see everything is working)
     
    I recently bought digital caliper and decided to try to read it's data port readings from my Launchpad. One of uses would be to use caliper for precise position sensor if 8Hz updates are enough. It had Clock and Data pin. Had to setup pin that connects to Clock to trigger interrup on every pulse and then in interrupt function do bit shifting to assemble 16 bit signed integer representing caliper reading. Then sent it out to PC via soft UART serial port. For that I reused examples from well known blog at http://www.msp430launchpad.com/.
     
    Also I had to figure out how to connect calipers lines to MSP430 as caliper is using 1.5V levels where MSP430 +3V levels. Used two transistors and two resistors and breadboard to amplify levels. Schematics:

     
    Also took caliper apart just to find out what principle is used to sense position changes:

     
    You can find full source code and detailed explanation in article I worte:
    http://robocombo.blogspot.com/2010/12/using-tis-launchpad-to-interface.html
     
    Let me know if you have any questions or suggestions!
  10. Like
    tingo reacted to username in Laser Security V2 Msp430   
    Hey All,
    Nate here. I'm currently a junior in EE and decided to use the msp430 in my Design 1 project(not senior design).
    Built a PCB and finalized most of the design.
    -Some basic features : LCD 16x2
    -120 db alarm (freaking loud)
    -1 5mw legal red laser
    -1 red led recieving diode
    -2 push buttons to enter in a code on the lcd screen
    Here some pics: (will upload a video of the operation when I get some time)
     


     

     

     

     

     
    Here is the schematic: (to big for site)
    http://img254.imageshack.us/img254/9838/lasersspdf.png
     
    and source code ( still in beta... needs abit of work as you tell)
     
    main.c

    // Laser Security System: // Code By Natahn Zimmerman // 11/9/11 /////////////Includes/////////////////// #include "msp430g2231.h" #include "lcd.h" /////////////LCD Defines//////////////// #define DATAPIN BIT6 #define CLOCKPIN BIT5 #define ENABLEPIN BIT4 //////////Other Micro Defines/////////// #define GLED BIT6 // Green LED saying that SS is good and active #define RLED BIT7 // Red LED saying that SS has been breached and alarm is high #define ALARM BIT7 // Also attached to RLED. #define TXD BIT0 // Serial Output #define RXD BIT1 // Serial Input #define SW1 BIT2 // Disable SS #define SW2 BIT3 // Disable SS //////////////Variables///////////////// volatile unsigned int i=1; // Variable for TXD Funciton. If this value goes above a certain point, security is breached. volatile unsigned int j=0; // Low State Check variable. This variable should increment to a certain point, if not, security is breached. volatile unsigned int t=0; // For loop variable for j. volatile unsigned int ticks=0; // Variable for Timer function. After this gets to a certain point alarm sounds. volatile unsigned int password=0; // value for number being keyed in on keypad. volatile unsigned int a = 0; // Password compare value volatile unsigned int c = 0; // Increment based upon password being correct. volatile unsigned int b = (0x80 | 0x40 | 0xA); // HD44780 Cursor location. char ptext[2]; // Password Char array. Bit 1 = password #, Bit 2 = null. //////////////PROTOS//////////////////// void TXD_RXD(void); // Prototype TXD Function void dis_alarm(void); //////////////Main////////////////////// void main(void) { _delay_cycles(20000); // debug delay WDTCTL = WDTPW + WDTHOLD; // turn off watchdog so micro does not reset _delay_cycles(100000); // debug delay P1OUT &= ~(CLOCKPIN + DATAPIN + RLED); //Set these pins low (ensures low when defined as output) P1OUT |= ENABLEPIN; // Set enable pin high. (ensures high when defined as output) P1DIR |= ENABLEPIN + CLOCKPIN + DATAPIN +RLED; // Define as outputs P1DIR &= ~(SW2 + SW1); // Define as perm inputs P1IE |= (SW1); // P1.2 interrupt enabled P1IFG &= ~(SW1); // P1.2 IFG cleared P1IE |= (SW2); // P1.3 interrupt enabled P1IFG &= ~(SW2); // P1.3 IFG cleared __enable_interrupt(); // enable all interrupts P2SEL = 0x00; // Set functionality of Port 2 to GPIO P2DIR |= GLED; // Set Green LED, AKA P2.6 AKA XIN to a output. P2OUT = 0; // Set all outputs on port 2 to 0. AKA GLED. P1DIR |= ( RLED + TXD); // All outputs except DIS_ALARM and RXD P1OUT &= ~(RLED +TXD); // All bits set high initally, need to set all bits low. P2OUT |= GLED; // Turns Green LED ON initDisplay(); // Turn on display. clearDisplay(); // Clear Display Print_Screen("Zalous Laser"); second_line(); Print_Screen("Security System"); _delay_cycles(5000000); clearDisplay(); Print_Screen("Laser System"); second_line(); Print_Screen("Now Activated"); _delay_cycles(20000); TXD_RXD(); // Should always stay in this state unless TXD != RXD. In which case the following happens: P2OUT &= ~GLED; // Green LED Turns off clearDisplay(); // Clear display for new text Print_Screen("Security System"); second_line(); Print_Screen("Breached! "); while(1) { P2OUT ^= GLED; // Blink Green LED CCTL0 = CCIE; // CCR0 interrupt enabled ( TIMER 1) CCR0 = 50000; // Set Timer Value TACTL = TASSEL_2 + MC_1; // Initialize Timer _delay_cycles(5000000); //Pause before enter password screen. clearDisplay(); Print_Screen("Please Enter"); second_line(); Print_Screen("Password: "); while(1) { if(ticks>500) // Ticks is a Timer Variable. User has 30 seconds to enter password before alarm sounds. { while(1) { P1OUT ^= RLED; //Pulse alarm. _delay_cycles(500000); } } } } } // End main void TXD_RXD(void) { while(i < 10) { P1OUT |= TXD; __delay_cycles(5); if((RXD & P1IN)==0) { i++; } P1OUT &= ~TXD; __delay_cycles(20); for(t=0;t<10;t++) { if((RXD & P1IN)==0) { j++; } } if(j>5) { j=0; } else { i++; } __delay_cycles(20); } // End While } // End Function void dis_alarm(void) { P1OUT &= ~TXD; for(i=0;i<10;i++) { _delay_cycles(300000); P2OUT ^= GLED; } WDTCTL = WDT_MRST_32 + ~WDTHOLD; } // Port 1 interrupt service routine #pragma vector=PORT1_VECTOR __interrupt void Port_1(void) { _delay_cycles(10); if(((SW1 & P1IN)) == 0) { password++; ptext[0] = password + '0'; ptext[1] = 0; _delay_cycles(2000); sendInstruction(b+a); _delay_cycles(2000); Print_Screen(ptext); _delay_cycles(2000); P2OUT ^= GLED; } if(((SW2 & P1IN)) == 0) { a++; _delay_cycles(2000); sendInstruction(b+a); _delay_cycles(2000); P2OUT ^= GLED; Print_Screen("_"); if(a==1) { if(password==3) { c++; } } if(a==2) { if(password==8) { c++; } } if(a==3) { if(password==9) { c++; } } if(a==4) { if(password==1) { c++; } } if(a==4) { if(password==2) { c++; c++; } } if(c==4) { CCTL0 &= ~CCIE; _delay_cycles(20000); __disable_interrupt(); _delay_cycles(120000); WDTCTL = WDT_MRST_32 + ~WDTHOLD; _delay_cycles(120000); } if(c==5) // debug feature. laser = always on. useful for { P1OUT = TXD; } // end if(a==4) { sendInstruction(b+a); Print_Screen(" "); a=0; c=0; sendInstruction(b+a); Print_Screen("_"); } // End If a == 4 password=0; } _delay_cycles(200000); P1IFG &= ~SW1; // P1.2 IFG cleared P1IFG &= ~SW2; // P1.3 IFG cleared } // End ISR #pragma vector=TIMERA0_VECTOR __interrupt void Timer_A (void) { P2OUT ^= GLED; // Toggle P1.0 ticks++; }
     
    and lcd.h (many thanks to RobG for his LCD code. Modified it abit and it works incredibly well! )
     

    #ifndef LCD_H_ #define LCD_H_ #define sendData(data) send(data, 1) #define sendInstruction(data) send(data, 0) #define initDisplay() sendInstruction(0x3C); sendInstruction(0x0C); clearDisplay(); sendInstruction(0x06) #define clearDisplay() sendInstruction(0x01); _delay_cycles(2000) #define second_line() sendInstruction((0x80 | 0x40)); _delay_cycles(2000) #define DATAPIN BIT6 #define CLOCKPIN BIT5 #define ENABLEPIN BIT4 void send(char data, char registerSelect); void sendDataArray(char data[], char length); void Print_Screen(char *texts); char charIndex = 0; char bitCounter = 0; void sendDataArray(char data[], char length) { charIndex = 0; while(charIndex < length) { sendData(data[charIndex]); charIndex++; } } void send(char data, char registerSelect) { bitCounter = 0; while(bitCounter < 8) { (data & BIT7) ? (P1OUT |= DATAPIN) : (P1OUT &= ~DATAPIN); data <<= 1; P1OUT |= CLOCKPIN; P1OUT &= ~CLOCKPIN; bitCounter++; } registerSelect ? (P1OUT |= DATAPIN) : (P1OUT &= ~DATAPIN); P1OUT &= ~ENABLEPIN; P1OUT |= ENABLEPIN; } void Print_Screen(char *texts) { volatile int i=0; char *h; h=texts; for(i=0;i<16;i++) { if(h[i]==0) { break; } } sendDataArray(h, i); } #endif /*LCD_H_*/

×
×
  • Create New...