Jump to content
43oh

jsolarski

Members
  • Content Count

    568
  • Joined

  • Last visited

  • Days Won

    8

Reputation Activity

  1. Like
    jsolarski reacted to hvontres in Diy High-Speed 20:1 Scope Probe   
    A while back I came across this Website:
    http://koti.mbnet.fi/jahonen/Electronics/DIY%201k%20probe/
     
    It is essentially a 1K resistor attached to a piece of 50 Ohm Coax. The original author did some performance testing on his probes and they are quite impressive for the investment. The original design has a 21:1 attenuation (1050 ohm/50 Ohm)
    I used two 470 Ohm resistors in Series to get closer to 20:1 (990 Ohm/50 ohm). One drawback of this probe design is that it needs to be terminated into 50 Ohms. My Tds 460A has a built in 50 Ohm termination. If your scope does not, you will also need an external 50 Ohm terminator for this to work correctly.
     
    Here are the scope traces for a standard 350Mhz 10:1probe (Channel 2) and a "homebrew" 20:1 probe (channel 4). Both probes were looking at the same pin. The scope used is an old Tek TDS 460A and the Bandwidth was limited to 100Mhz.
     
     

     
    On a 1Mhz clock, the 10:1 probe shows a little overshoot, but not much distortion.
     

     
    On the 16 Mhz Clock signal, the 10:1 Probe shows significant distortion and overshoot due to it's capacitance. The 20:1 probe shows a nearly trapezoidal wave shape with no overshoot in the corners. I think a couple of these probes would be a useful addition to all of our toolboxes.
  2. Like
    jsolarski reacted to Cannonadek in New Parts   
    So I got some new items. I needed some 10 pin headers and my local shop wanted like $5 for a 15 pin. That was just way too much for something that I would need to modify to make it work. So I went online and found an awesome store. While I was there I also got this LCD thing. http://www.surplusgizmos.com/16x2-LCD-H ... p_597.html not bad for $5 bucks. Now I just need a reason to use it . I just thought I would let you know about these, and this online store.
  3. Like
    jsolarski reacted to oPossum in 12 voice polyphonic wavetable synth with G2211   
    PWM audio output on P1.6.
     
    Uses NCO with 16 or 32 bit precision. No interpolation due to lack of hardware multiplier on G2211.
     

    ; synth.asm .cdecls C, LIST, "msp430g2211.h" smplrt .equ 38400 ; Sample rate ph32 .equ 0 ; Use 32 bit phase .text .global set_tick .global get_tick .global synth_init .global set_note .bss tick, 2 .if ph32 .bss phase_inc, 4 * 12 ; Phase increment LSW/MSW (from note table) .bss phase_acc, 4 * 12 ; Phase accumulator LSW/MSW .else .bss phase_inc, 2 * 12 ; Phase increment (from note table) .bss phase_acc, 2 * 12 ; Phase accumulator .endif set_tick mov R12, &tick ret get_tick mov &tick, R12 ret synth_init mov #0x0210, &TACTL ; Timer A config: SMCLK, count up ;mov #511, &TACCR0 ; Setup Timer A period for 31250 sps mov #415, &TACCR0 ; Setup Timer A period for 38400 sps mov #256, &TACCR1 ; Setup Timer A compare mov #0x00E0, &TACCTL1 ; Setup Timer A reset/set output mode ; mov #phase_inc, R12 ; Clear all phase inc and accum .if ph32 ; mov #4 * 12, R14 ; Word count .else ; mov #2 * 12, R14 ; Word count .endif ; 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, &TACCTL1 ; Enable PWM interupt ret synth_isr push R4 push R5 push R6 push R7 push R8 push R9 mov #sine, R4 ; Get wavetable pointer mov #phase_inc, R5 ; Setup phase increment pointer .if ph32 ; mov #phase_acc + 2, R6 ; Setup phase accumulator pointer .else ; mov #phase_acc, R6 ; Setup phase accumulator pointer .endif ; clr R7 ; Clear sample accumulator mov #12, R8 ; Setup voice count voice_loop ; mov @R6, R9 ; Get phase acc (MSW) swpb R9 ; Swap MSB/LSB mov.b R9, R9 ; Clear MSB add R4, R9 ; Add wavetable pointer mov.b @R9, R9 ; Get wave sample add R9, R7 ; Update sample .if ph32 ; add @R5+, -2(R6) ; Update phase acc addc @R5+, 0(R6) ; add #4, R6 ; Increment phase acc pointer .else ; add @R5+, 0(R6) ; Update phase acc incd R6 ; Increment phase acc pointer .endif ; dec R8 ; Dec voice count jne voice_loop ; Next voice... ; rra R7 ; rra R7 ; rra R7 ; add #16, R7 ; mov R7, &TACCR1 ; Output sample ; dec &tick ; jc $ + 6 ; clr &tick ; ; bic #0x01, &TACCTL1 ; ; pop R9 pop R8 pop R7 pop R6 pop R5 pop R4 reti set_note clr R14 ; Clear octave count cmp #128, R12 ; jhs note_off ; tst_note ; cmp #116, R12 ; Within note table? jge get_pi ; Yes... inc R14 ; Inc octave count add #12, R12 ; Add octave to note jmp tst_note ; Check again... get_pi ; Get phase increment sub #116, R12 ; Adjust for first note in table rla R12 ; MIDI note * 2 .if ph32 ; rla R12 ; MIDI note * 2 (* 4 total) add #notes, R12 ; Add note table pointer mov @R12+, R15 ; Get LSW .else ; add #notes, R12 ; Add note table pointer .endif ; mov @R12, R12 ; Get MSW tst R14 ; Shifting required? jeq set_phase ; No... shift_phase ; rra R12 ; Shift phase inc .if ph32 ; rrc R15 ; .endif ; dec R14 ; Dec octave count jne shift_phase ; Repeat until zero... set_phase ; rla R13 ; Voice * 2 .if ph32 ; rla R13 ; Voice * 2 (* 4 total) add #phase_inc, R13 ; Add phase inc pointer mov R15, 0(R13) ; Set phase inc mov R12, 2(R13) ; .else ; add #phase_inc, R13 ; Add phase inc pointer mov R12, 0(R13) ; Set phase inc .endif ; ret ; Return ; note_off ; rla R13 ; Voice * 2 .if ph32 ; rla R13 ; Voice * 2 (* 4 total) .endif ; mov R13, R12 ; Copy add #phase_inc, R12 ; Phase inc pointer add #phase_acc, R13 ; Phase accum pointer clr 0(R12) ; Clear phase inc clr 0(R13) ; Clear phase accum .if ph32 ; clr 2(R12) ; clr 2(R13) ; .endif ; ret ; Return ; ; notes ; MIDI Note Frequency .if smplrt == 31250 ; 31250 sps .if ph32 ; .long 913264688 ; 116 G#8 6644.875 .long 967570232 ; 117 A8 7040.000 .long 1025104952 ; 118 A#8 7458.620 .long 1086060865 ; 119 B8 7902.133 .long 1150641405 ; 120 C9 8372.018 .long 1219062103 ; 121 C#9 8869.844 .long 1291551308 ; 122 D9 9397.273 .long 1368350945 ; 123 D#9 9956.063 .long 1449717327 ; 124 E9 10548.082 .long 1535922005 ; 125 F9 11175.303 .long 1627252680 ; 126 F#9 11839.822 .long 1724014160 ; 127 G9 12543.854 .else ; .word 13935 ; 116 G#8 6644.726 .word 14764 ; 117 A8 7040.024 .word 15642 ; 118 A#8 7458.687 .word 16572 ; 119 B8 7902.145 .word 17557 ; 120 C9 8371.830 .word 18601 ; 121 C#9 8869.648 .word 19708 ; 122 D9 9397.507 .word 20879 ; 123 D#9 9955.883 .word 22121 ; 124 E9 10548.115 .word 23436 ; 125 F9 11175.156 .word 24830 ; 126 F#9 11839.867 .word 26306 ; 127 G9 12543.678 .endif ; .endif ; ; .if smplrt == 38400 ; 38400 sps .if ph32 ; .word 743216706 ; 116 G#8 6644.875 .word 787410671 ; 117 A8 7040.000 .word 834232546 ; 118 A#8 7458.620 .word 883838595 ; 119 B8 7902.133 .word 936394372 ; 120 C9 8372.018 .word 992075279 ; 121 C#9 8869.844 .word 1051067145 ; 122 D9 9397.273 .word 1113566850 ; 123 D#9 9956.063 .word 1179782981 ; 124 E9 10548.082 .word 1249936527 ; 125 F9 11175.303 .word 1324261621 ; 126 F#9 11839.822 .word 1403006315 ; 127 G9 12543.854 .else ; .word 11341 ; 116 G#8 6645.117 .word 12015 ; 117 A8 7040.039 .word 12729 ; 118 A#8 7458.398 .word 13486 ; 119 B8 7901.953 .word 14288 ; 120 C9 8371.875 .word 15138 ; 121 C#9 8869.922 .word 16038 ; 122 D9 9397.266 .word 16992 ; 123 D#9 9956.250 .word 18002 ; 124 E9 10548.047 .word 19073 ; 125 F9 11175.586 .word 20207 ; 126 F#9 11840.039 .word 21408 ; 127 G9 12543.750 .endif ; .endif ; sine .byte 128 .byte 131 .byte 134 .byte 137 .byte 140 .byte 144 .byte 147 .byte 150 .byte 153 .byte 156 .byte 159 .byte 162 .byte 165 .byte 168 .byte 171 .byte 174 .byte 177 .byte 179 .byte 182 .byte 185 .byte 188 .byte 191 .byte 193 .byte 196 .byte 199 .byte 201 .byte 204 .byte 206 .byte 209 .byte 211 .byte 213 .byte 216 .byte 218 .byte 220 .byte 222 .byte 224 .byte 226 .byte 228 .byte 230 .byte 232 .byte 234 .byte 235 .byte 237 .byte 239 .byte 240 .byte 241 .byte 243 .byte 244 .byte 245 .byte 246 .byte 248 .byte 249 .byte 250 .byte 250 .byte 251 .byte 252 .byte 253 .byte 253 .byte 254 .byte 254 .byte 254 .byte 255 .byte 255 .byte 255 .byte 255 .byte 255 .byte 255 .byte 255 .byte 254 .byte 254 .byte 254 .byte 253 .byte 253 .byte 252 .byte 251 .byte 250 .byte 250 .byte 249 .byte 248 .byte 246 .byte 245 .byte 244 .byte 243 .byte 241 .byte 240 .byte 239 .byte 237 .byte 235 .byte 234 .byte 232 .byte 230 .byte 228 .byte 226 .byte 224 .byte 222 .byte 220 .byte 218 .byte 216 .byte 213 .byte 211 .byte 209 .byte 206 .byte 204 .byte 201 .byte 199 .byte 196 .byte 193 .byte 191 .byte 188 .byte 185 .byte 182 .byte 179 .byte 177 .byte 174 .byte 171 .byte 168 .byte 165 .byte 162 .byte 159 .byte 156 .byte 153 .byte 150 .byte 147 .byte 144 .byte 140 .byte 137 .byte 134 .byte 131 .byte 128 .byte 125 .byte 122 .byte 119 .byte 116 .byte 112 .byte 109 .byte 106 .byte 103 .byte 100 .byte 97 .byte 94 .byte 91 .byte 88 .byte 85 .byte 82 .byte 79 .byte 77 .byte 74 .byte 71 .byte 68 .byte 65 .byte 63 .byte 60 .byte 57 .byte 55 .byte 52 .byte 50 .byte 47 .byte 45 .byte 43 .byte 40 .byte 38 .byte 36 .byte 34 .byte 32 .byte 30 .byte 28 .byte 26 .byte 24 .byte 22 .byte 21 .byte 19 .byte 17 .byte 16 .byte 15 .byte 13 .byte 12 .byte 11 .byte 10 .byte 8 .byte 7 .byte 6 .byte 6 .byte 5 .byte 4 .byte 3 .byte 3 .byte 2 .byte 2 .byte 2 .byte 1 .byte 1 .byte 1 .byte 1 .byte 1 .byte 1 .byte 1 .byte 2 .byte 2 .byte 2 .byte 3 .byte 3 .byte 4 .byte 5 .byte 6 .byte 6 .byte 7 .byte 8 .byte 10 .byte 11 .byte 12 .byte 13 .byte 15 .byte 16 .byte 17 .byte 19 .byte 21 .byte 22 .byte 24 .byte 26 .byte 28 .byte 30 .byte 32 .byte 34 .byte 36 .byte 38 .byte 40 .byte 43 .byte 45 .byte 47 .byte 50 .byte 52 .byte 55 .byte 57 .byte 60 .byte 63 .byte 65 .byte 68 .byte 71 .byte 74 .byte 77 .byte 79 .byte 82 .byte 85 .byte 88 .byte 91 .byte 94 .byte 97 .byte 100 .byte 103 .byte 106 .byte 109 .byte 112 .byte 116 .byte 119 .byte 122 .byte 125 ; Interrupt Vectors .sect ".int08" ; TACCR1 CCIFG, TAIFG .short synth_isr ; ; .end ;
     
    Some code to test it...

    // main.c #include "msp430g2211.h" void set_tick(unsigned); unsigned get_tick(void); void synth_init(); void set_note(int, unsigned); void main(void) { unsigned n; WDTCTL = WDTPW + WDTHOLD; BCSCTL1 = XT2OFF + 15; P1DIR = 0xF2; // I/O assignment P1REN = 0x0D; // Pull up resistor for switch and Rxd P1OUT = 0x0F; // Pull up, serial idle high P1SEL = 0x50; // Enable Timer A output, SMCLK output synth_init(); #if 0 set_note(33, 0); // A1 55 Hz set_note(45, 1); // A2 110 Hz set_note(57, 2); // A3 220 Hz set_note(69, 3); // A4 440 Hz set_note(81, 4); // A5 880 Hz set_note(93, 5); // A6 1760 Hz set_note(105, 6); // A7 3520 Hz set_note(117, 7); // A8 7040 Hz #endif #if 0 set_note(69, 0); // A4 440 Hz set_note(70, 1); // set_note(71, 2); // set_note(72, 3); // set_note(73, 4); // set_note(74, 5); // set_note(75, 6); // set_note(76, 7); // set_note(77, 8); // set_note(78, 9); // set_note(79, 10); // set_note(80, 11); // #endif #if 1 n = 57; for(; { set_note(0x7F & n++, 0); set_tick(5000); while(get_tick()); set_note(-1, 0); set_tick(1000); while(get_tick()); } #endif for(;; }
     
    Working on MIDI support so it can play music.
  4. Like
    jsolarski reacted to MattTheGeek in Just a reminder...   
    When EasyMSP is released as a Beta or Alpha, It contains NO DOCUMENTATION. Only proper and official releases get documentation. EasyMSP Betas are normally released to show what the final release will include and is only a preview. These Betas are not expected to work properly, and are normally just to show that i'm am really working on it and not just slacking off
     
    However for Release Candidates (RC), They will include proper documentation and are expected to work. I Expect to release a RC about June 15th or earlier.
     
    Regards,
    MattTheGeek
  5. Like
    jsolarski reacted to bluehash in LCR Meter Smart Tweezers Discount Code   
    Might as well put it in here. As it says on the main blog:
    LCR Meter Smart Tweezers - Discount code SOFF43OH
  6. Like
    jsolarski reacted to bluehash in msp430afe253 TSSOP on a Schmartboard   
    Good work pheo!. Do you have any plans for it?
     
    For the lazy:
  7. Like
    jsolarski reacted to pheo in msp430afe253 TSSOP on a Schmartboard   
    So, today, i got my 0.65mm SOIC Schmartboard in the mail, and i'd like to share the result.
     
    The chip i've got is a msp430afe253ipwr, a very nice little chip with a lot of great features.
    I'm very proud to announce i've gotten it working with the Launchpad.
     
    The Schmartboard is a SOIC to DIP adapter available (cheaply!) from a few distributors.
    http://www.schmartboard.com/index.asp?page=products_smttodip&id=449
     
    A few notes about using the Schmartboard:
    I pulled this off using a very cheap 7$ department store soldering iron.
    That said, the lack of a good tip, good wattage, and a VERY steady hand prevented me from using the Schmartboards "super easy groove soldering" setup/trick.
    I read somewhere that when doing SMT soldering, use more solder!
    This may seem counter-intuitive, but adding LOTS of solder, and then wicking off the excess with solder braid seems to be a good practice.
     
    Anyhow, everything is working. All gpio ports, VCC, ground, RST, and TEST are connected. I don't know if there are any bridges yet, but all the gpio's will light the LED with P1DIR = P2DIR = 0xff.
     
    Im using the bleeding edge uniarch gcc and the git mspdebug. While gcc knows all about the afe253, mspdebug doesn't. I told mspdebug to treat the chip as a g2553, as they both have the same flash and ram size.
     
    Everything seems to work great.
     
    Cheers!

  8. Like
    jsolarski reacted to gordon in Beginner Questions   
    Depends on what you consider "supported" or what your needs/expectations are. As I have said before, with mspgcc4+mspdebug+vim I'm a perfectly happy hippo. There's also Insight for debugging, but it proved a bit shaky when I tried to use it (it's probably better with newer mspdebugs).
     
    Officially, CCS5.1 will (is said to) have proper Linux support. I don't really mind about it (except for trying to fish the compiler out and use it separately, without the Eclipse insanity).
     
    As for information, we have two topics, viewtopic.php?f=8&t=46 and viewtopic.php?f=8&t=449 dedicated to the subject. Book-wise the lot seems to have converged on MSP430 Microcontroller Basics (Amazon affiliate link with commission going to this blog).
     
    There is also a link to a quite comprehensive-looking tutorial (PDF) somewhere in the forums, but I can't find it now. Edit: found it: viewtopic.php?p=4479#p4473 (http://glitovsky.com/blog/?p=85).
     
    If you are new to programming in general, you also should pick up some C literature as well. Generally, K&R is everyone's first answer here, but according to a valued member while it teaches you C, it doesn't really teach you programming as such, so - depending on your previous experience - you may want to pick something else.
  9. Like
    jsolarski reacted to pheo in Hardware UART Skeleton in C   
    My first forum post, i'd like to help out anyone trying to use the USCI module for hardware UART.
     
    First, some background:
    I'm running the Launchpad with a msp430g2553. This chip is very full featured, comes in PDIP-20 compatible with the Launchpad, and if you're lucky, TI will send you a sample. See the datasheet:
    http://focus.ti.com/docs/prod/folders/print/msp430g2553.html
     
    I'm running uniarch msp430-gcc-4.5.2, which is the awesome alpha release.
    For a nice how-to-compile link, try:
    http://sourceforge.net/apps/mediawiki/mspgcc/index.php?title=Devel:UniarchGit
    This worked well for me on Fedora, as does the new gcc.
    Check out the bleeding edge mspdebug from git for full debugger support as well:
    http://mspdebug.sourceforge.net
    With the right devel packages, this guy works like a charm with the g2553.
     
    Well, the g2553 has the TX/RX pins for the USCI module flipped from the Launchpad TX/RX headers!
    So how can that be fixed? I didn't have any tools or hardware to correct the problem. Just some wire and a soldering pencil.
    Why not just the hardware from the Launchpad? It has extra jumpers for the LED's and a strip of male pin headers. (i used the female headers). See the attached image.
     
    I plan on using HW UART to act a transceiver. For my next project, i'd like to be able to send/receive data to/from the Launchpad so that it can use it in a second stage of sending/receiving. Since i've gotten the code for the first stage working, i think the place i am at could serve as a big leg up to anyone working on a project that needs to be "remote controlled" in a complex way.
     
    Now for the code:
    The flow of the program is as follows
    1. Setup the button on the launchpad. i do this, because otherwise the LP will start spewing characters over serial and this breaks my ttyACM0. Im not sure why, but the driver doesn't seem to like
    2. After the button is pressed, setup the USCI module.
    I'm using 32.768 kHz ACLK as the clock source, UART mode, at 9600 baud
    3. Spew out the alphabet in a loop.
    3.1. During the main loop, the receive interrupt will write down what it got into a variable, conveniently named 'variable'.
     
    Hopefully this will help someone out.
    There's a lot more to be done. This is just a nice guidepost on the way.
     
    Cheers
     
    EDIT: Found a bug

    Makefile.txt
    main.c
  10. Like
    jsolarski reacted to MarkoeZ in A Noobs Introduction to MSP430 - Serial RC Car Video Blog   
    Well not much to post on the main project yet, mainly doing research. But since this is still a noobs introduction: I discovered about soundcard oscilloscopes yesterday night, and started experimenting with it this evening. Pretty nice stuff for (near) nothing
     
    MarkoeZ MSP430 Launchpad Video's Part 9: PC Soundcard Oscilloscope for testing:
     
    Cheers!
  11. Like
    jsolarski reacted to gordon in mspgcc4 gcc vs. g++ code size   
    Any of you guys noticed that (probably only in certain circumstances/on certain code details of which I have not worked out) g++ tends to compile (sometimes substantially) smaller code than gcc (talking about MSPGCC4 that is)?
     
    gcc:

    $ msp430-gcc -Os -Wall -W -Wextra -Werror -g -mendup-at=main -mmcu=msp430x2211 -c main.c $ msp430-gcc -mmcu=msp430x2211 -o main.elf main.o $ msp430-objdump -DS main.elf > main.lst $ msp430-size main.elf text data bss dec hex filename 904 0 28 932 3a4 main.elf
     
    g++:

    $ msp430-g++ -Os -Wall -W -Wextra -Werror -g -mendup-at=main -mmcu=msp430x2211 -c main.c $ msp430-g++ -mmcu=msp430x2211 -o main.elf main.o $ msp430-objdump -DS main.elf > main.lst $ msp430-size main.elf text data bss dec hex filename 782 0 28 810 32a main.elf
     
    That's ~15% off of .text in this particular case, which is like a ~6% memory expansion for free.
     
    Nothing scientific about this yet, but if you are squeezing the last bits out of your MCU, this might save you an upgrade.
  12. Like
    jsolarski reacted to zeke in Programmable load begging for an MSP430 mod   
    I was reading Dangerous Prototypes newsfeed this morning and I spotted a link to a programmable load article.
     
    This may be a useful product for someone out there doing a power supply project. Had I won a recent contract bid :cry: , it would have been infinitely useful to me for my product torture testing phase. I would have been able to dynamically and remotely adjust the load on the power supplies inside of a temperature testing chamber.
     
    Since the project is open source, I thought I should mention it here. It's not based on an MSP430 but I suspect that it could be modified appropriately
  13. Like
    jsolarski reacted to gwdeveloper in Another BMP085 Project   
    Hey guys, I managed to get the BMP085 running on the new MSP-EXP430F5529 dev board. Still putting the final touches on the application but it will initially be a basic weather station. Getting the BMP085 was one of the tougher parts of the programming.
     
    The display is showing temperature, pressure and time. Eventually, it will look like a weather station plot like http://www.srh.noaa.gov/jetstream/synoptic/wxmaps.htm
     
    Since the USCI was used, I'm pretty sure that all of this code, with minor modifications, would run on a MSP430G2553. I may attempt that later on today but the RC truck is screaming for attention (and it's in a thousand pieces on the dining table).
     
    Begin BMP085.c

    /****************************************************************/ /* Greg Whitmore */ /* greg@gwdeveloper.net */ /* gwdevprojects.blogspot.com */ /****************************************************************/ /* released under the "Use at your own risk" license */ /* use it how you want, where you want and have fun */ /* debugging the code. */ /* MSP-EXP430F5529 */ /****************************************************************/ // currently this is only configured for OSS = 0 // future changes will allow for extended oversampling // standard includes #include #include #include "itoa.h" // driver includes #include "HAL_Board.h" #include "HAL_Buttons.h" #include "HAL_Dogs102x6.h" #include "HAL_Menu.h" #include "HAL_MACROS.h" #include "clock.h" #include "bmp085.h" #include "iic.h" extern char time[9]; extern char date[9]; extern unsigned char *PTxData; // Pointer to TX data extern unsigned char TXByteCtr; extern unsigned char *PRxData; // Pointer to RX data extern unsigned char RXByteCtr; extern volatile unsigned char RxBuffer[3]; // Allocate 3 bytes of RAM, it's all we need here // types based from API // if initialize more than 1 var per line, the calculations are off // cal data int ac1; int ac2; int ac3; unsigned int ac4; unsigned int ac5; unsigned int ac6; int b1; int b2; int mb; int mc; int md; // true temp long ut; long x1; long x2; long b5; int bmp_temp = 0; //true pressure long up; long x3; long b3; unsigned long b4; long b6; unsigned long b7; long p; long bmp_pres = 0; // tx constants const unsigned char utTxData[] = { BMP085_CTRL_REG, BMP085_TEMP_REG }; // uncomp temp reg const unsigned char upTxData[] = { BMP085_CTRL_REG, BMP085_PRESSURE_REG }; // oss =0 see bmp085.h const unsigned char msbData[] = { BMP085_MSB_REG }; // read calibration data from prom - optimize? load all 22 bytes 1 shot? void bmp085_cal(void){ Dogs102x6_clearScreen(); Dogs102x6_stringDrawXY(4, 0, "Loading", DOGS102x6_DRAW_NORMAL); Dogs102x6_stringDrawXY(8, 10, "Calibration", DOGS102x6_DRAW_NORMAL); // store PROM data into usable variables ac1 = sendByte_getBytes(BMP085_ADDR, 0xAA, 2); __delay_cycles(1000); ac2 = sendByte_getBytes(BMP085_ADDR, 0xAC, 2); __delay_cycles(1000); ac3 = sendByte_getBytes(BMP085_ADDR, 0xAE, 2); __delay_cycles(1000); ac4 = sendByte_getBytes(BMP085_ADDR, 0xB0, 2); __delay_cycles(1000); ac5 = sendByte_getBytes(BMP085_ADDR, 0xB2, 2); __delay_cycles(1000); ac6 = sendByte_getBytes(BMP085_ADDR, 0xB4, 2); __delay_cycles(1000); b1 = sendByte_getBytes(BMP085_ADDR, 0xB6, 2); __delay_cycles(1000); b2 = sendByte_getBytes(BMP085_ADDR, 0xB8, 2); __delay_cycles(1000); mb = sendByte_getBytes(BMP085_ADDR, 0xBA, 2); __delay_cycles(1000); mc = sendByte_getBytes(BMP085_ADDR, 0xBC, 2); __delay_cycles(1000); md = sendByte_getBytes(BMP085_ADDR, 0xBE, 2); __delay_cycles(1000); // write to flash here and only run on intitial puc - not implemented yet Dogs102x6_clearScreen(); } // read uncompensated temperature and return msb & lsb unsigned int bmp085_ut(void){ iic_tx_init(BMP085_ADDR); __delay_cycles(1000); PTxData = (unsigned char *)utTxData; // send control reg and temp reg TXByteCtr = 2; // Load TX byte counter start_TX(); __delay_cycles(112505); // ? ~4.5ms at 25mhz ? 25001 * 4.5 // function returns ints return (sendByte_getBytes(BMP085_ADDR, BMP085_MSB_REG, 2)); } // read uncompensated pressure and return msb, lsb & xlsb unsigned long bmp085_up(void){ iic_tx_init(BMP085_ADDR); __delay_cycles(1000); PTxData = (unsigned char *)upTxData; // send control reg and temp reg TXByteCtr = 2; // Load TX byte counter start_TX(); __delay_cycles(112505); // ? ~4.5ms at 25mhz ? 25001 * 4.5 PTxData = (unsigned char *)msbData; // send msb read register TXByteCtr = 1; start_TX(); iic_rx_init(); // set RX interrupt __delay_cycles(1000); PRxData = (unsigned char *)RxBuffer; // rx buffer RXByteCtr = 3; // number of bytes to receive start_RX(); // returning longs instead of ints to allow 2^16 shifts return ( (( (long)RxBuffer[0] << 16) | ( (long)RxBuffer[1] << 8) | (long)RxBuffer[2]) >> 8); } void get_bmp085(){ unsigned char temp_buffer[8]; unsigned char pres_buffer[8]; bmp085_cal(); Dogs102x6_clearScreen(); Dogs102x6_stringDraw(0, 1, "GWDev BMP085", NORMAL); // header Dogs102x6_circleDraw(50, 34, 8, NORMAL); // circle for weather symbol while (!(buttonsPressed & BUTTON_S2)){ DigitalClockUpdate(); Dogs102x6_stringDraw(7, 0, &time[HOUR10], NORMAL); // clock here for demo ut = bmp085_ut(); up = bmp085_up(); // calc true temp x1 = ((long)ut - ac6) * ac5 >> 15; x2 = ((long)mc << 11) / (x1 + md); b5 = x1 + x2; bmp_temp = (b5 + 8) >> 4; // itoa function added itoa(bmp_temp, (char*)temp_buffer); // move integer into char buffer Dogs102x6_stringDraw(2, 24, (char*)temp_buffer, NORMAL); // display temperature on weather symbol // // calc true pressure b6 = b5 - 4000; x1 = (b2 * (b6 * b6) >> 12) >> 11; x2 = (ac2 * b6) >> 11; x3 = x1 + x2; b3 = ((long)ac1 * 4 + x3 + 2) >> 2; // ???? so many 'corrections' on the web this one works though x1 = ac3 * b6 >> 13; x2 = (b1 * ((b6 * b6) >> 12)) >> 16; x3 = ((x1 + x2) + 2) >> 2; b4 = (ac4 * (unsigned long)(x3 + 32768)) >> 15; b7 = ((unsigned long)up - b3) * 50000; //p = b7 < 0x80000000 ? (b7 * 2) / b4 : (b7 / b4) * 2; // ???? noobness - unsure of the formatting, below works // or if (b7 < 0x80000000) { p = (b7 * 2) / b4;} else {p = (b7 / b4) *2;} // x1 = (p >> 8) * (p >> 8); x1 = (x1 * 3038) >> 16; x2 = (-7357 * p) >> 16; bmp_pres = p + ((x1 + x2 + 3791) >> 4); // ltoa, part of stdlib.h ltoa(bmp_pres, (char*)pres_buffer); // move long integer into char buffer Dogs102x6_stringDraw(2, 60, (char*)pres_buffer, NORMAL); // display pressure on weather symbol // __delay_cycles(500000); } }
     
    Begin BMP085.h

    /****************************************************************/ /* Greg Whitmore */ /* greg@gwdeveloper.net */ /* gwdevprojects.blogspot.com */ /****************************************************************/ /* released under the "Use at your own risk" license */ /* use it how you want, where you want and have fun */ /* debugging the code. */ /* MSP-EXP430F5529 */ /****************************************************************/ #ifndef BMP085_H_ #define BMP085_H_ /* BMP085 Register Definitions */ #define BMP085_ADDR 0x77 #define BMP085_CTRL_REG 0xF4 #define BMP085_TEMP_REG 0x2E #define BMP085_PRESSURE_REG 0x34 // oss =0 #define BMP085_PRESSURE_REG_OSS1 0x74 // oss =1, longer delays needed 7.5ms #define BMP085_PRESSURE_REG_OSS2 0xB4 // oss =2, 13.5ms #define BMP085_PRESSURE_REG_OSS3 0xF4 // oss =3, 25.5ms #define BMP085_MSB_REG 0xF6 #define BMP085_LSB_REG 0xF7 #define BMP085_CONV_REG_XLSB 0xF8 // prototypes void bmp085_cal(void); unsigned int bmp085_ut(void); unsigned long bmp085_up(void); void get_bmp085(void); #endif /*BMP085_H_*/
     
    Begin iic.c

    /****************************************************************/ /* Greg Whitmore */ /* greg@gwdeveloper.net */ /* gwdevprojects.blogspot.com */ /****************************************************************/ /* released under the "Use at your own risk" license */ /* use it how you want, where you want and have fun */ /* debugging the code. */ /* MSP-EXP430F5529 */ /****************************************************************/ #include #include "HAL_Board.h" #include "HAL_Buttons.h" #include "HAL_Dogs102x6.h" #include "bmp085.h" #include "iic.h" unsigned char *PTxData; // Pointer to TX data unsigned char TXByteCtr; unsigned char *PRxData; // Pointer to RX data unsigned char RXByteCtr; volatile unsigned char RxBuffer[3]; // Allocate 3 byte of RAM /* ignore remapping for now, iic needs to be moved from UCB0 to UCB1 const uint8_t iic_remap[] = { PM_UCB1SDA, PM_UCB1SCL, }; */ /* ignore this remap for now * * void remap_iic() { PMAPPWD = 0x02D52; PMAPCTL |= PMAPRECFG; P4MAP6 = PM_UCB1SDA; P4MAP7 = PM_UCB1SCL; P4SEL = BIT6+BIT7; UCB1CTL1 |= UCSWRST; // Enable SW reset UCB1CTL0 = UCMST + UCMODE_3 + UCSYNC; // I2C Master, synchronous mode UCB1CTL1 = UCSSEL_2 + UCSWRST; // Use SMCLK, keep SW reset UCB1BR0 = 12; // fSCL = SMCLK/12 = ~100kHz UCB1BR1 = 0; UCB1I2COA = 0x01; UCB1I2CSA = 0x48; // Slave Address is 048h UCB1CTL1 &= ~UCSWRST; // Clear SW reset, resume operation UCB1IE |= UCTXIE; // Enable TX interrupt } * */ // initialize iic void iic_init(void){ P3SEL |= 0x03; // Assign I2C pins to USCI_B0 UCB0CTL1 |= UCSWRST; // Enable SW reset UCB0CTL0 = UCMST + UCMODE_3 + UCSYNC; // I2C Master, synchronous mode UCB0CTL1 = UCSSEL_2 + UCSWRST; // Use SMCLK, keep SW reset UCB0BR0 = 0; // "fSCL = SMCLK/12 = ~100kHz" ----supposedly, UCB0BR1 = 0; // but any values for UCB0BR cause system to run funny UCB0I2COA = 0x43; // set own address UCB0CTL1 &= ~UCSWRST; // Clear SW reset, resume operation } void iic_tx_init(unsigned char slave_reg){ UCB0I2CSA = slave_reg; UCB0IE |= UCTXIE; // Enable TX interrupt } void iic_rx_init(void){ UCB0IE |= UCRXIE; // enable RX interrupt } // send 1 byte, return 2 bytes - needs the return expanded for X bytes int sendByte_getBytes(unsigned char slave_addr, unsigned char reg_2_read, int bytes_to_rx){ // transmit slave address and register to read iic_tx_init(slave_addr); __delay_cycles(1000); PTxData = (unsigned char *)&reg_2_read; // TX array start address TXByteCtr = sizeof reg_2_read; // Load TX byte counter start_TX(); // // receive requested bytes iic_rx_init(); // set RX interrupt __delay_cycles(1000); PRxData = (unsigned char *)RxBuffer; // rx buffer RXByteCtr = bytes_to_rx; // number of bytes to receive start_RX(); // return ((int)RxBuffer[0] << 8) | (int)RxBuffer[1]; // currently only returning 2 bytes } // start transmitting void start_TX(void){ UCB0CTL1 |= UCTR + UCTXSTT; // I2C TX, start condition __bis_SR_register(LPM0_bits + GIE); // Enter LPM0, enable interrupts __no_operation(); // Remain in LPM0 until all data // is TX'd while (UCB0CTL1 & UCTXSTP); // Ensure stop condition got sent } // restart and receive void start_RX(void){ while (UCB0CTL1 & UCTXSTP); // wait for stop UCB0CTL1 &= ~UCTR; // restart, set as receiver UCB0CTL1 |= UCTXSTT; // start condition __bis_SR_register(LPM0_bits + GIE); while (UCB0CTL1 & UCTXSTP); } // initial isr code combined from TI I2C examples for MSP430F5529 // ucsi BO isr states #pragma vector = USCI_B0_VECTOR __interrupt void USCI_B0_ISR(void) { switch(__even_in_range(UCB0IV,12)) { case 0: break; // Vector 0: No interrupts case 2: break; // Vector 2: ALIFG case 4: // Vector 4: NACKIFG break; case 6: // Vector 6: STTIFG UCB0IFG &= ~UCSTTIFG; // Clear start condition int flag break; case 8: // Vector 8: STPIFG UCB0IFG &= ~UCSTPIFG; // Clear stop condition int flag __bic_SR_register_on_exit(LPM0_bits); // Exit LPM0 if data was transmitted break; case 10: // Vector 10: RXIFG RXByteCtr--; // Decrement RX byte counter if (RXByteCtr) { *PRxData++ = UCB0RXBUF; // Move RX data to address PRxData if (RXByteCtr == 1) // Only one byte left? UCB0CTL1 |= UCTXSTP; // Generate I2C stop condition } else { *PRxData = UCB0RXBUF; // Move final RX data to PRxData __bic_SR_register_on_exit(LPM0_bits); // Exit active CPU } break; case 12: // Vector 12: TXIFG if (TXByteCtr) // Check TX byte counter { UCB0TXBUF = *PTxData++; // Load TX buffer TXByteCtr--; // Decrement TX byte counter } else { UCB0CTL1 |= UCTXSTP; // I2C stop condition UCB0IFG &= ~UCTXIFG; // Clear USCI_B0 TX int flag __bic_SR_register_on_exit(LPM0_bits); // Exit LPM0 } default: break; } }
     
    Begin iic.h

    /****************************************************************/ /* Greg Whitmore */ /* greg@gwdeveloper.net */ /* gwdevprojects.blogspot.com */ /****************************************************************/ /* released under the "Use at your own risk" license */ /* use it how you want, where you want and have fun */ /* debugging the code. */ /* MSP-EXP430F5529 */ /****************************************************************/ #ifndef IIC_H_ #define IIC_H_ void remap_iic(void); void iic_init(void); void iic_tx_init(unsigned char slave_reg); void start_TX(void); void iic_rx_init(void); void start_RX(void); int sendByte_getBytes(unsigned char slave_addr, unsigned char reg_2_read, int bytes_to_rx); #endif /*IIC_H_*/
  14. Like
    jsolarski reacted to Rickta59 in Interface 23K256 SPI RAM with USI SPI   
    I came across the Microchip 23K256 Serial RAM device a while back. It seems to fit the bill
    when you need more RAM but don't want to spend a lot of money to get it. These chips are
    inexpensive, (about $1,50 at time of this post 06/05/2011) and hold 32K worth of data. You access
    the memory using SPI. You can even put multiple 23K256 devices on your SPI bus and get
    even more buffer space.
     
    The arduino world already has a couple of libraries to access these devices. I adapted
    one of these to work with both CCS and the uniarch compiler.
     
    I used GRACE to help me configure the msp430g2452 USI in SPI Mode 1. This code might be
    also be useful as a starting point for any SPI Mode 1 device. This code is written for the USI
    device. It would be nice to have a USCI version that would work with the g2553 chip.
     
    Typical use for this device might be to buffer UART received data that is larger than the 128 bytes
    of SRAM available on the smaller G series chips.
     
    You might want to verify the pin setup, I think I have it correct, however you should always verify.
    One interesting item of note is my use of one of the GPIO pins to power the device. You may or
    may not want to use that in your setup. According to the datasheet the 23K256 uses somewhere
    between 2-10mA of power based on how fast you interface with it. I think the G series should
    handle that but I'm not 100% sure. Please comment if you know.
     
    https://gist.github.com/1009412
     

    /** * testspi23K256.c - Interface Microchip 23K256 Serial RAM chip with MSP430G2452 USI SPI * * This code snippet show you how to configure the USI SPI in SPI Mode 1 to communicate with * the 23K256 chip at 4MHz. It takes about 98uSecs to write a single byte and 32K takes * about 100ms. * * msp430g2452 - http://focus.ti.com/docs/prod/folders/print/msp430g2452.html * 23K256 - http://www.microchip.com/wwwproducts/Devices.aspx?dDocName=en539039 * * Pin Connections: * * MSP430 SCLK P1.5 -> PIN 6(SCK) 23K256 * MSP430 MISO P1.7 -> PIN 2(SO) 23K256 * MSP430 MOSI P1.6 -> PIN 5(SI) 23K256 * MSP430 GPIO P1.1 -> PIN 1(CS) 23K256 * MSP430 GPIO P1.4 -> PIN 8(VCC) 23K256 * * 23K256 PIN 7 Pullup resistor * 23K256 PIN 8 Pulldown resistor * * Linux build: * * $ msp430-gcc -mmcu=msp430g2452 -O3 -g -Wall -I. -c testspi23K256.c * $ msp430-gcc -mmcu=msp430g2452 -O3 -g -Wall -I. -o ./testspi23K256.elf ./testspi23K256.o -Wl,-Map,./testspi23K256.map * $ msp430-objdump -Sww ./testspi23K256.elf >./testspi23K256.lss * $ msp430-size ./testspi23K256.elf * $ mspdebug -q --force-reset rf2500 "erase" "prog ./testspi23K256.elf" * * This code was inspired from this code: * * http://sourceforge.net/projects/mysudoku/files/ * http://hackaday.com/2009/03/02/parts-32kb-spi-sram-memory-23k256/ * */ #include #include enum { POWER_PIN = BIT4, // we power the 23K256 chip from one of our GPIO pins SS_PIN = BIT1, // CS , active low DEBUG_PIN = BIT0, // toggle on and off marking time to write DUMMY_BYTE = 0xFF // byte we send when we just want to read slave data }; static inline uint8_t RWData(volatile uint8_t value); void loop(); #define powerOn P1OUT |= POWER_PIN #define powerOff P1OUT &= ~POWER_PIN #define ssSelect P1OUT &= ~SS_PIN #define ssDeselect P1OUT |= SS_PIN #define delay_1ms __delay_cycles(16000) #define SR_WRITE_STATUS 0x01 #define SR_WRITE 0x02 #define SR_READ 0x03 #define SR_READ_STATUS 0x05 // 23K256 Serial Ram functions uint8_t SR_getMode(void) { ssSelect; RWData(SR_READ_STATUS); // 0x05 uint8_t mode = RWData(DUMMY_BYTE); ssDeselect; return mode; } void SR_setMode(uint8_t mode) { ssSelect; RWData(SR_WRITE_STATUS); // 0x01 RWData(mode); ssDeselect; } static inline void SR_writestream(uint16_t addr) { ssDeselect; // deselect if we are active ssSelect; RWData(0x02); RWData(addr >> 8); RWData(addr); } static inline void SR_readstream(uint16_t addr) { ssDeselect; ssSelect; RWData(0x03); RWData(addr >> 8); RWData(addr); } static inline uint8_t RWData(volatile uint8_t value) { USISRL = value; USICNT = 8; // initialize bit count, start transfer/read __delay_cycles(0); while (!(USIIFG & USICTL1)) ; // wait for SPI flag to trip return USISRL; } /** * main */ int main() { // kill the watchdog timer WDTCTL = WDTPW + WDTHOLD; // configure DCO clock to 16MHz BCSCTL2 = SELM_0 + DIVM_0 + DIVS_0; if (CALBC1_16MHZ != 0xFF) { DCOCTL = 0x00; BCSCTL1 = CALBC1_16MHZ; DCOCTL = CALDCO_16MHZ; } BCSCTL1 |= XT2OFF + DIVA_0; BCSCTL3 = XT2S_0 + LFXT1S_2 + XCAP_1; // configure GPIO P1OUT = POWER_PIN; P1DIR = SS_PIN + POWER_PIN + DEBUG_PIN; // configure USI - SPI Mode 1 @ 4MHz, clocked off SMCLK USICTL0 |= USISWRST; USICTL0 = USIPE7 + USIPE6 + USIPE5 + USIMST + USIOE + USISWRST; USICTL1 |= USICKPH; USICKCTL = USIDIV_1 + USISSEL_2; /* Enable USI */ USICTL0 &= ~USISWRST; __enable_interrupt(); // Set global interrupt enable // toggle the power for the 23K256 powerOff; delay_1ms; powerOn; ssDeselect; delay_1ms; while (1) { uint8_t chipMode; // make sure there is a 23K256 chip and that // is wired properly and in sequential mode chipMode = SR_getMode(); if (chipMode != 0x41) { SR_setMode(0x41); } else { while (1) { loop(); } } } } #define BYTES_TO_STREAM 32768 // should be less <= 32768 #define PATTERN_BYTE_VALUE 0x55 /** * loop - write a test pattern and read it back */ void loop() { volatile uint16_t i; volatile uint8_t storedValue = 0; P1OUT |= DEBUG_PIN; // mark start of write for measurement with oscope SR_writestream(0); // start writing at address 0 for (i = 0; i < BYTES_TO_STREAM; ++i) { RWData(PATTERN_BYTE_VALUE); } P1OUT &= ~DEBUG_PIN; // mark end of write for measurement with oscope // verify the bytes we wrote were stored and retreived properly SR_readstream(0); // start reading at address 0 for (i = 0; i < BYTES_TO_STREAM; ++i) { storedValue = RWData(DUMMY_BYTE); // verify our test pattern if (storedValue != PATTERN_BYTE_VALUE) { // if values aren't the same an error occurred, // turn off all leds, then sit and spin P1OUT &= ~BIT6; P1OUT &= ~DEBUG_PIN; while (1) { ; } } } }
  15. Like
    jsolarski reacted to MarkoeZ in A Noobs Introduction to MSP430 - Serial RC Car Video Blog   
    Hello people.
    I've been experimenting with the msp430, and working toward a goal. But thought i'd document every step. That way creating a complete video blog of the project, from the first steps, to hopefully something unique.
     
    So for now this is mainly for people new to microcontrollers and are interested in the Launchpad, or just bought one and don't know what to do with it. 43oh veterans: Probably not for you, but if you see errors in the video's please tell me so i can insert notes about them for future viewers
     
    Enjoy!:
     
    MarkoeZ MSP430 Launchpad Video's Part 1: Audio Intro
     
    MarkoeZ MSP430 Launchpad Video's Part 2: First part of the package contents
     
    MarkoeZ MSP430 Launchpad Video's Part 4: The Standard Temperature Sensing Program(with pc serial connection)
     
    MarkoeZ MSP430 Launchpad Video's Part 5: Leds and Buttons
     
    MarkoeZ MSP430 Launchpad Video's Part 6: Leds controlled through PC Serial Connection
     
    MarkoeZ MSP430 Launchpad Video's Part 7: Soldering, connections, and more
     
    MarkoeZ MSP430 Launchpad Video's Part 8: Created my LaunchPad Plugon Test Board
     
    MarkoeZ MSP430 Launchpad Video's Part 9: PC Soundcard Oscilloscope for testing:
     
    MarkoeZ MSP430 Launchpad Video's Part 10: Introducing a Porsche (rc car) Loud Noise Warning!!
     
    MarkoeZ MSP430 Launchpad Video's Part 11:RC Car controlled through PC Serial. Loud Noise Warning!!
     
    MarkoeZ MSP430 Launchpad Video's Part 12: Serial RC car, added connectors and first drive test!
     
    MarkoeZ MSP430 Launchpad Video's Part 13: The first Sensor, Cheap, but working, IR LED Collision Detection

     
    MarkoeZ MSP430 Launchpad Video's Part 14: Started work on the Car Drive Program *Noise Warning!*

     
    MarkoeZ MSP430 Launchpad Video's Part 15: Introducing an OpenPandora and an FT232RL usb to serial chip

     
    MarkoeZ MSP430 Launchpad Video's Part 16A: Created plugin sensors

     
    MarkoeZ MSP430 Launchpad Video's Part 16B: Plugin IR sensor test, and tools overview

     
    MarkoeZ MSP430 Launchpad Video's Part 17: Porsche with USB! Hardware building and status overview

     
    MarkoeZ MSP430 Launchpad Video's Part 18: Standalone G2252 First Tests, serial communication too

     
    MarkoeZ MSP430 Launchpad Video's Part 19: MSP on batteries, Main Board for the car updated with IR, power led and more

     
    MSP430 Launchpad Video 20: Porsche Nightrider Shiftregister

     
    MSP430 Launchpad Video 21: PWM On Board Leds, controlled by launchpad Serial

     
    MSP430 Launchpad Video 22: Added a button to the car and cut up the board

     
    MSP430 Intermediate 23: First Drive Test of the RC Porsche standalone!

     
    EDIT March-2-2012: Just noticed i never added the final thing. So, here it goes!
     
    My Contest Entry:
     
    A Porsche Model Car with an MSP430G2252, movement, speed and (just for fun) shiftregister LEDs controlled over usb Serial by a Pandora Console.
    With custom written Gui, And Touchscreen, D-Pad and ActionButton drive/program select.
    And yes, wireless is next, but still deciding what hardware i want.
     
    But the Video's show it pretty well, Enjoy!
     
    Drive Tests:


     
    Software overview and Final tests before drive:


     
    Some other video's i kept private till now:
     
    Very first Pandora gui test:

     
    First PC serial test with all modules connected, also nice overview of the individual modules:


     
     
    From the pandora you have basic drive control obviously, but also the PWM can be adjusted by single values, or 6 pre set steps, starting at 0 and increasing 20% with each step, and slider/buttons for quick selection.
    Also, just for fun, i added some commands to change the led blinking mode
     
    Components:
     
    MSP430 Main Car Control and Interface Board - Contains all the connections for the individual modules, as well as the Controller
    Parts:
    * 1 MSP430G2252
    * 1 20 pin DIP Chipsocket
    * 4 NPN Transistors
    * 4 2.2kohm Resistors
    * 1 33kohm Resistor
    * 1 470ohm Resistor
    * 1 470nF Capacitor
    * 1 Orange T1 LED
    * About a row of male Pin Headers
    * lots of connection cables (i use old hard drive IDE cables for everything)
     
     
    Shift Register Led Control Board - A shift Register built onto a small module containing all resistors for led drive
    Parts:
    * 1 74HC595 Shift Register
    * Chipsocket optional, i just soldered onto the board
    * 6 1kohm resistors (for the slightly dimmed knightrider leds, and one for the board power led)
    * 1 Orange T1 LED
    * about 1/4 of a row of male Pin Headers
    * connection cable (i use old hard drive IDE cables for everything)
    * min 5 port female Pin Header
     
    FT232R BreakoutBoard by Sparkfun
    Simply soldered male Pin Headers to it, and glued female headers with a cable inside the car. Instant usb module.
     
    Built into the car:
    * 5x T1 LED for the knightrider effect
    * 1 pushbutton
    * 5 pin female header with connection cables for the usb->serial module glued in.
     
    An OpenPandora - Gui is only functional for pandora atm. But any device capable of USB serial can drive it, using a terminal, or a Gui. It's only sending out to the car atm, so a simple "echo blabla" is enough.
     
    First rough schematics, Mind that these are the first schematics i have ever drawn in my life. I would like some constructive critics, but be gentle
     
    [attachment=0]PandoraPorschechematics.png[/attachment]
     
    And the code, again, might be rough at the edges:

    #include #include "stdbool.h" #include //add for interrupt #define PERIOD 200 //defines frequency volatile int timer = 0; //counts how many interrupts have been called //resets when it counts to PERIOD volatile int duty_cycle = 90;// max = PERIOD - 1 and min = 1 #define TXD BIT1 // TXD on P1.1 #define RXD BIT2 // RXD on P1.2 #define Bit_time 104 // 9600 Baud, SMCLK=1MHz (1MHz/9600)=104 #define Bit_time_5 52 // Time for half a bit. // Code for the ShiftRegister driving the LED's #define SHIFTDATA BIT7 // Shiftregister Data on P1.7 #define SHIFTCLOCK BIT7 // Shiftregister Clock Pulse on P2.7 #define SHIFTLATCH BIT6 // Shiftregister Latch Pulse on P2.6 #define STEERLEFT BIT4 // Left steering on P2.4 #define STEERRIGHT BIT5 // right steering on P2.5 bool shiftbit[8]; // array used to contain the shiftregister serial bits int activeled = 0; // used for led animation bool ledup = 1; int ledcounter = 0; int shifttimer = 0; // Timer to control shiftregister output speeds int blinkmode = 0; // 0 is knightrider, 1 is up and down bar, 2 is blinketyblink int steeringmode = 0; // 0 is neutral, 1 is left, 2 is right (right broken here though) void pulseShiftClock ( void ); void pulseShiftLatch ( void ); void setShiftReg ( void ); // ASCII values for the commands #define MODE0 0x30 // serial 1 #define MODE1 0x31 // serial 1 #define MODE2 0x32 // serial 2 #define MODE3 0x33 // serial 3 #define MODE4 0x34 // serial 4 #define MODE5 0x35 // serial 5 #define MODE6 0x36 // serial 6 #define MODE7 0x37 // serial 7 #define MODE8 0x38 // serial 8 #define PWMMODE0 0x61 // serial a #define PWMMODE1 0x62 // serial b #define PWMMODE2 0x63 // serial c #define PWMMODE3 0x64 // serial d #define PWMMODE4 0x65 // serial e #define PWMMODE5 0x66 // serial f #define BLINKMODE0 0x69 // serial i #define BLINKMODE1 0x6A // serial j #define BLINKMODE2 0x6B // serial k #define LED_SENSE INCH_6 // Photodiode connected to P1.6 unsigned int adcval = 0; // used for light sensing, nor really used in this case unsigned int timerCount = 0;// tomer for the sensing unsigned char BitCnt; // Bit count, used when transmitting byte unsigned int TXByte; // Value sent over UART when Transmit() is called unsigned int RXByte; // Value recieved once hasRecieved is set unsigned int drivestate = 0;// Dive neutral, forward or backward unsigned int i; // for loop variable bool isReceiving; // Status for when the device is receiving bool hasReceived; // Lets the program know when a byte is received void Transmit(void); void Receive(void); unsigned int analogRead(unsigned int pin) { // analog reading code, not really used in this case ADC10CTL0 = ADC10ON + ADC10SHT_2 + SREF_1 + REFON + REF2_5V; ADC10CTL1 = ADC10SSEL_0 + pin; ADC10CTL0 |= ENC + ADC10SC; while (1) { if ((ADC10CTL1 ^ ADC10BUSY) & ((ADC10CTL0 & ADC10IFG)==ADC10IFG)) { ADC10CTL0 &= ~(ADC10IFG +ENC); break; } } return ADC10MEM; } void main(void) { unsigned int i, delay; WDTCTL = WDT_MDLY_0_064; // Watchdog Timer interval setting if (CALBC1_1MHZ ==0xFF || CALDCO_1MHZ == 0xFF) { while(1); // If cal constants erased, trap CPU!! } BCSCTL1 = CALBC1_1MHZ; // Set range DCOCTL = CALDCO_1MHZ; // Set DCO step + modulation P1SEL |= TXD; // Connected TXD to timer P1DIR |= TXD; P1IES |= RXD; // RXD Hi/lo edge interrupt P1IFG &= ~RXD; // Clear RXD (flag) before enabling interrupt P1IE |= RXD; //P1DIR = 0X41; // set both leds to output // and set them off initially P2DIR |= 0X0A; //set P2 Drive pins P2DIR |= STEERLEFT; P2DIR |= STEERRIGHT; P1DIR |= SHIFTDATA; // set shiftregister data pin output P2DIR |= SHIFTCLOCK; // set shiftregister clock and latch pins to output P2DIR |= SHIFTLATCH; P2SEL = 0x00; // allow 2.6-2.7 to output P1OUT = 0; // Set both ports outputs to zero initially P2OUT = 0; isReceiving = false; // Set initial values hasReceived = false; IE1 |= WDTIE; __enable_interrupt(); // Enable interrupts __bis_SR_register(GIE); // interrupts enabled\ while(1) { shifttimer++; if (shifttimer == 2000) // The led animation and shiftregister main loop code { shifttimer = 0; if (blinkmode == 0 ) { if (ledup == 1) { activeled++; if(activeled == 4){ledup = 0;} } else { activeled--; if(activeled == 0){ledup = 1;} } for (i = 0; i < 8;i++) { if (i == activeled) { shiftbit[i] = 1; } else { shiftbit[i] = 0; } } } else if (blinkmode == 1) { if (ledup == 1) { activeled++; if(activeled == 4){ledup = 0;} } else { activeled--; if(activeled == 0){ledup = 1;} } for (i = 0; i < 8;i++) { if (i <= activeled) { shiftbit[i] = 1; } else { shiftbit[i] = 0; } } } else if (blinkmode == 2) { for (i = 0; i < 8;i++) { if (shiftbit[i] == 0) { shiftbit[i] = 1; } else {shiftbit[i] = 0;} } } setShiftReg(); } if (hasReceived) // If the device has recieved a value { Receive(); } if (drivestate == 9) // the sensing mode, not really used in this case { adcval = 0; for ( i=0; i < 8; i++ ) { adcval += analogRead(LED_SENSE ); // Read the analog input. delay = 1000; while (--delay); } if (adcval < 800 ){ drivestate = 1; duty_cycle = 110; delay = 1000000000; while (--delay); delay = 1000000000; while (--delay); delay = 1000000000; while (--delay); duty_cycle = 90; drivestate = 0; } } } } /** * Handles the received byte and calls the needed functions.\ **/ void Receive() { hasReceived = false; // Clear the flag switch(RXByte) // Switch depending on command value received { case MODE0: // don't drive drivestate = 0; break; case MODE1: // slow down if(duty_cycle >= 2) { duty_cycle--; } break; case MODE2: // drive backward drivestate = 2; break; case MODE3: // switch drive direction if (drivestate == 0){drivestate = 1;} else {drivestate = 0;} break; case MODE4: // steer left P2OUT &= ~STEERRIGHT; P2OUT |= STEERLEFT; steeringmode = 1; break; case MODE5: // center steering P2OUT &= ~STEERLEFT; P2OUT &= ~STEERRIGHT; steeringmode = 0; break; case MODE6: // steer right P2OUT &= ~STEERLEFT; P2OUT |= STEERRIGHT; steeringmode = 2; break; case MODE7: // speed up if(duty_cycle <= 198) { duty_cycle++; } break; case MODE8: // drive forward drivestate = 1; break; case PWMMODE0: duty_cycle = 1; break; case PWMMODE1: duty_cycle = 40; break; case PWMMODE2: duty_cycle = 80; break; case PWMMODE3: duty_cycle = 120; break; case PWMMODE4: duty_cycle = 160; break; case PWMMODE5: duty_cycle = 199; break; case BLINKMODE0: blinkmode = 0; break; case BLINKMODE1: blinkmode = 1; break; case BLINKMODE2: blinkmode = 2; break; default:; } } /** * Transmits the value currently in TXByte. The function waits till it is * finished transmiting before it returns. **/ void Transmit() { while(isReceiving); // Wait for RX completion TXByte |= 0x100; // Add stop bit to TXByte (which is logical 1) TXByte = TXByte << 1; // Add start bit (which is logical 0) BitCnt = 0xA; // Load Bit counter, 8 bits + ST/SP CCTL0 = OUT; // TXD Idle as Mark TACTL = TASSEL_2 + MC_2; // SMCLK, continuous mode CCR0 = TAR; // Initialize compare register CCR0 += Bit_time; // Set time till first bit CCTL0 = CCIS0 + OUTMOD0 + CCIE; // Set signal, intial value, enable interrupts while ( CCTL0 & CCIE ); // Wait for previous TX completion } #pragma vector=PORT1_VECTOR __interrupt void Port_1(void) { isReceiving = true; P1IE &= ~RXD; // Disable RXD interrupt P1IFG &= ~RXD; // Clear RXD IFG (interrupt flag) TACTL = TASSEL_2 + MC_2; // SMCLK, continuous mode CCR0 = TAR; // Initialize compare register CCR0 += Bit_time_5; // Set time till first bit CCTL0 = OUTMOD1 + CCIE; // Dissable TX and enable interrupts RXByte = 0; // Initialize RXByte BitCnt = 0x9; // Load Bit counter, 8 bits + ST } /** * Timer interrupt routine. This handles transmiting and receiving bytes. **/ #pragma vector=TIMER0_A0_VECTOR __interrupt void Timer_A (void) { if(!isReceiving) { CCR0 += Bit_time; // Add Offset to CCR0 if ( BitCnt == 0) // If all bits TXed { TACTL = TASSEL_2; // SMCLK, timer off (for power consumption) CCTL0 &= ~ CCIE ; // Disable interrupt } else { CCTL0 |= OUTMOD2; // Set TX bit to 0 if (TXByte & 0x01) CCTL0 &= ~ OUTMOD2; // If it should be 1, set it to 1 TXByte = TXByte >> 1; BitCnt --; } } else { CCR0 += Bit_time; // Add Offset to CCR0 if ( BitCnt == 0) { TACTL = TASSEL_2; // SMCLK, timer off (for power consumption) CCTL0 &= ~ CCIE ; // Disable interrupt isReceiving = false; P1IFG &= ~RXD; // clear RXD IFG (interrupt flag) P1IE |= RXD; // enabled RXD interrupt if ( (RXByte & 0x201) == 0x200) // Validate the start and stop bits are correct { RXByte = RXByte >> 1; // Remove start bit RXByte &= 0xFF; // Remove stop bit hasReceived = true; } __bic_SR_register_on_exit(CPUOFF); // Enable CPU so the main while loop continues } else { if ( (P1IN & RXD) == RXD) // If bit is set? RXByte |= 0x400; // Set the value in the RXByte RXByte = RXByte >> 1; // Shift the bits down BitCnt --; } } } #pragma vector=WDT_VECTOR __interrupt void watchdog_timer(void) { ++timer; if (timer == PERIOD) { timer = 0; if (drivestate == 1) // forward drive pwm { P2OUT |= BIT1; } else if (drivestate == 2) // backward drive pwm { P2OUT |= BIT3; } } if (timer == duty_cycle ) { P2OUT &= ~BIT1; P2OUT &= ~BIT3;} //end interrupt } void setShiftReg() // Sends the values of shiftbit[i] to the shiftregister { for (i = 0; i < 8; i++) { if (shiftbit[i] == 1) { P1OUT |= SHIFTDATA; } else { P1OUT &= ~SHIFTDATA; } pulseShiftClock(); P1OUT &= ~SHIFTDATA; } pulseShiftLatch(); } void pulseShiftClock() // pulse shiftregister clock pin { P2OUT |= SHIFTCLOCK; P2OUT &= ~SHIFTCLOCK; } void pulseShiftLatch() // pulse shiftregister latch pin { P2OUT |= SHIFTLATCH; P2OUT &= ~SHIFTLATCH; }
     
    Hope that was helpful
     
    Cheers!
     
    MarkoeZ
  16. Like
    jsolarski reacted to gordon in Beginner's inventory needs   
    So You Want to Build Electronics is a nicely done blog post by our member PhirePhly on the ever-popular subject of "so I want to build electronics, what inventory do I need to get started?".
  17. Like
    jsolarski reacted to zeke in I know this is oooooold... but still funny   
    I know this video is old but I still think it's hilarious:
     
    Weird Al - White and Nerdy.
     
    I think Donny Osmond is pretty funny in
    .
  18. Like
    jsolarski reacted to gatesphere in Trick for exposing female leads from male pin headers   
    Hi all, I just came up with a neat trick for getting female leads from a male-populated board. My MSP-EXP430FR5739 (which was so graciously gifted to me by a member of this forum ) came with male headers prepopulated. I don't really have much use for male headers, but I didn't want to unsolder the male pins because I'm sloppy and tend to lift traces when I do that... so I came up with this solution, involving two pin jumpers I had pulled from an old motherboard ages ago, and female headers that came packaged with the board. Check it out.
     

     
    Thought this might help someone out there
  19. Like
    jsolarski reacted to zeke in State Machine Example Code   
    Hi Guys,
     
    I've been thinking about the topic of state machines lately and I thought I'd try to whip up a posting on my approach to state machines.
     
    I've written a state machine for my client but I can't post that without a lot of changes. So I'm going to convert it into a traffic light state machine example.
     
    Hmmm... I just realized that I should talk about what a state machine is but I haven't got anything prepared yet. So, for now, I'll assume you know what it is.
     
    Here's my definitions and declarations:
     

    #include // add header file for MSP430G2231 device. #include #define VERSION(id, rev, tag) const char id##_version[] = "@(#)Id:" #id " Ver:" rev " Released by:" tag " Built:" __DATE__ " " __TIME__ #define INPUT 0 #define OUTPUT 1 #define TRUE 1 #define FALSE 0 #define HIGH 1 #define LOW 0 #define TOGGLE 2 #define nothing1 BIT0 // P1.0, 0x01, 0b0000 0001 #define onGREENLED BIT1 // P1.1, 0x02, 0b0000 1000 #define onREDLED BIT2 // P1.2, 0x04, 0b0001 0000 #define nothing2 BIT3 // P1.3, 0x08, 0b0000 0010 #define nothing3 BIT4 // P1.4, 0x10, 0b0000 0100 #define onYELLOWLED BIT5 // P1.5, 0x20, 0b0010 0000 #define nothing4 BIT6 // P1.6, 0x40, 0b0100 0000 #define nothing5 BIT7 // P1.7, 0x80, 0b1000 0000 #define TIMEBASE 16384 // This is selected ACLK/2, Production value = 16384 #define STARTTIMEOUT 5 // 5 seconds #define OVERALLTIMEOUT 43200 // 12hr*60min*60sec = 43200 seconds /******************************************************************************* * Global Variables * ******************************************************************************/ unsigned char TimerTick;
     
     
     
    So, here's my main function and interrupt routine. This will configure the msp430 to interrupt every TIMEBASE counts. In this case, the result is an interrupt every 0.25 seconds.
     

    void main(void) { WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer BCSCTL1 = CALBC1_1MHZ; DCOCTL = CALDCO_1MHZ; BCSCTL3 |= XCAP_3; // Launchpad watch crystals need ~12.5 pF // Configure all IO's and their default states on the MSP430 InitMSP430(); InitIOs(); // Initialize the system tick count TimerTick = 0; // Initialize all state machines InitTimerStateMachine(); InitTrafficLightStateMachine(); VERSION(TrafficLightStateMachineExample, "Alpha1", "Zeke"); _BIS_SR( GIE ); // Sooner or later, you're gonna have to Enter LPM3 w/ interrupt while(1) { // May have to add some servicing routines in here that aren't controlled by the 1 second timer // This is a place holder. // Decide on whether you're going to use an infinite loop or send the micro into LPM3 mode w/ Interrupts enabled. } } // Period of this interrupt is set in InitMSP430 #pragma vector=TIMERA0_VECTOR __interrupt void Timer_A(void) { // Update the system tick count every interrupt TimerTick++; // Update these state machines every 1 second if( TimerTick % 2 ) { UpdateTimerStateMachine(); UpdateTrafficLightStateMachine(); } // Update the output state of each control line every 0.5 seconds UpdateIOs(); }
     
     
    And here's my InitMSP430() function:

    /******************************************************************************* * InitMSP430() * * Initializes the resources of the MSP430 for this program. * ******************************************************************************/ void InitMSP430( void ) { // Configure these I/O pins to outputs pinModeP1( onGREENLED, OUTPUT ); pinModeP1( onREDLED, OUTPUT ); pinModeP1( onYELLOWLED, OUTPUT ); // Set these Outputs to default states digitalWriteP1( onGREENLED, HIGH ); digitalWriteP1( onREDLED, HIGH ); digitalWriteP1( onYELLOWLED , HIGH ); // Configure the TimerA to run at a 1 second rate CCTL0 = CCIE; // CCR0 interrupt enabled CCR0 = TIMEBASE-1; // 0.25 second timer operation TACTL = TASSEL_1 + MC_1; // ACLK, upmode }
     
    So, these are the files that will lay the foundation for a well balanced state machine. In this example, I'm going to simulate a traffic light state machine. It seems to me that it is the example that every prof uses in control systems lab class.
     
    I haven't posted up the routines that really matter yet. Namely, the UpdateStateMachine() functions. They are the gears in this transmission.
     
    So, stay tuned for more. I hope you will like this.
  20. Like
    jsolarski reacted to zeke in Ethernet to serial module?   
    I received my Stellaris S2E kit today. It's a neat little device.
     
    The serial interface board is kinda weird but I understand why they stacked it up that way. The USB cable is there to supply power to the target board. Sneaky.
     
    I like the little webserver on-board. It's slow but it's there so that you can configure the communication parameters.
     
    The telnet interface is cool. Telnet to x.x.x.x:23 for port1 and x.x.x.x:26 for port2. You've gotta have a terminal connected to the DB9 serial port connector to perform end to end testing.
     
    I see this as a reference design device. It should be adapted to your application - whatever that might be.
     
    I can see this being successfully adapted as an LP shield board. It would need a complete board respin and some new code created.
     
    I can also see this ref design being successfully adapted as an ethernet to Zigbee link board. Again, a new board would be created to accommodate a Digi board and the code could be modified to be able to configure the Digi module.
     
    I'm going to keep playing with this module. I may even get a second one so that I can try a long S2E2S link configuration.
     
    All in all, I think it's a 9 out of 10 on the Nerdy Cool Scale

  21. Like
    jsolarski reacted to cde in Source for good old easy to solder, er, solder   
    Just want to mention, if you ever need good old fashion, easy to melt and remelt 60/40 Tin/Lead+Flux solder, check your local dollar store. Lead-free solder sucks.
  22. Like
    jsolarski reacted to gordon in The portable LaunchPad   
    No, really. The portable LaunchPad .
     
    Some time back I inherited a big pile of used, impractical-to-reuse DAT tapes. They've been lying around not doing much useful, but the arrival of the LaunchPad triggered an idea: their cases are ideal containers for small stuff.
     
    I keep an LP and a separate box of assorted random junk in my backpack all the time; they are safe (the cases are quite sturdy and close well), and are always at hand, should some time for a hacking session be found.
     

    Add a third one with one of these tiny breadboards and a couple of flexible jumper wires, and you have a full-fledged lab-on-the-go in space less than two packs of cigarettes .
     
    The cases also make nice storage for components in general -- a bit hard to fish things out of them (definitely harder than these storage units with drawers), on the plus side it's also much harder to spill half a million stingy beasts on the carpet.
  23. Like
    jsolarski reacted to bluehash in Private message spam   
    You may have noticed a PM from a spammer. We apologize for that. Private messaging has been now limited to 3 recipients(at a time) only and a 1 minute wait time between messages.
  24. Like
    jsolarski reacted to fj604 in Disconnect LED2 to use I2C on Launchpad   
    The SCK line for on MSP430G2231 is the same as P1.6, which is connected to LED2 on the Launchpad. SCK is supposed to be pulled up for I2C to work, therefore you will have to disconnect the jumper J5 - 1.
     
    If you do not, LED2 will glow a faint green as it is would be connected to VCC through a pullup, and I2C will not work at all.
     
    This took me a while to figure - I thought I'd share.
  25. Like
    jsolarski got a reaction from zeke in MSP430 data acquisition from multiple sensors   
    check out this article
    http://alumni.cs.ucr.edu/~amitra/sdcard ... _foust.pdf
     
    and http://en.wikipedia.org/wiki/Text_file
     
    from what i understand, a txt file is a header and an EOF marker and data in-between the markers. as long as your SD card is formatted in FAT you should be able to just write header, then the data and close it out with an EOF marker and should be able to read it. If you can write files with dd then you should be able to write them with a Uc lol
     
     
    Try formatting the SD card in fat and then try writing a zero- byte file and then go from there
×
×
  • Create New...