Jump to content


  • Content Count

  • Joined

  • Last visited

  • Days Won


Posts posted by enl

  1. @roadrunner: Single pnp directly driven by the output of the MSP430 might be ok, but, given the current requirement of the LEDs with all segments on, the base current would likely be enough to cause significant drop at the pin. In itself not a big issue,but the variation between, say, a 1 and an 8 would cause a visible difference in brightness, given the low drop across  the current limit resistors. Remember, that transistor is driving all 7 anodes.



    Also, that would not allow for a higher anode supply than the 3.3V of the MSP430. Higher supply for the LEDs gives more stiffness in the current against load changes, and, therefore, more stable intensity.

  2. As an additional note, if you are willing to let the brightness be moderately low, you could get by without the uln2803, as each output will only  be driving a single led at a time, and use the npn transistor as an emitter follower. The display you selected is 20mA max continuous, 30mA peak. The outputs of the MSP430g2553 can sink 20mA with about 0.5V to 0.7 drop at 3.3V (SLAS735J fig7), and a total of 48mA sink or source (SLAS735J P24), and will have a drop of a bit less than 0.25V at 5mA sink. This suggests to me that if you limit the current of the LEDs to 5mA or so, you can pick them based on a drop of 3.3V-2V-0.6V-0.25V=0.45V (drop at 5mA from graph, emitter follower drop presuming <0.5mA base current at high, and midrange drop of LED) with a max sink of 35mA. This is in the safe, if not ideal, region of design, giving a limit resistor of 100 ohms (nominal current will be about 4.6mA). At 91ohms (5% series, but not one many people keep in the quantity of the factors of 10) you would be, nominally, right at 5mA, but with brightness more sensitive to variation in components. at 120ohms, you'd be at 3.75mA. As I said, going this way you will be at the dim side. The 100ohm will put you at about 1/2 or a tad less of the perceived max brightness for a single display run without multiplex. The numbers make it look like about 1/13 (1/3 of 1/(20/4.6)), but, due to the flicker of multiplexing, it is perceived brighter than the actual average, and the human eye is non-linear on top of that.


    Would I do it this way for NASA? no. For a commercial product? This is a lot less sketchy than many things done in commercial products, and is well within the data sheet specs, so I absolutely would, given the savings in component cost and size.



    Edit: attach circuit schematics to show described options, drawn crudely with clipart and MS PAINT, because they are handy on my beater laptop. I don't think I made any major errors.


    Edit 2: left out the base resistor on the bottom right. I really shouldn't do these on MSpaint during a useless meeting......


  3. Old thread, but I am curious about two things:


    What was the final purchase, if any? (I may have missed this in another thread, but a quick search didn't show me)




    Does anyone have exposure to the Carbide3D Nomad yet? They have apparently been delivering since late '14, but I have found no reviews (in several hours of reading/searching) from an actual user. Lots from the time frame of the kickstarter and just after, but nothing in the form of "I have a production model and have used it". I would love an Othermill but have no interest or need for a Mac to drive it,and am uninterested in rolling or modifying my own software. Given that I don't forsee having a suitable space for a full size mill anytime soon, and this specs to do 80% of what I need in a mill, the rest being either too large or in steel, I am intrigued.

  4. @@JohnDough --


    The MSP430G launchpad kit includes a 32.768KHz crystal. It is not installed and you will need to solder it on place. I would not call it a beginner soldering job, but it isn't bad as small components go. I would use the supplied crystal, as it will fit the pads on the board and is matched to the internal oscillator driver. You will need to check the specs before programming if you use a different one, as you may need to change the load capacitance from the sample code.


    ULN2803 is fine with the LED displays you selected, but see the following for why I don't think you want to go this way.. They are common anode, so each channel of the IC will pull down a a segment for each display, power supply permitting.


    The non transistors are not what you want for the high side at 3.3V, as you will drop 1V (give or take) across the uln2803, and another 0.7V across the npn transistor (maybe more with drop in the MSP430 output) on the anode since it will need to be used as an emitter follower. This leaves about 1.6V for the LED and current limit resistor. The LED needs 1.8 min (up to 2.2v), and it is a good idea to have at least 0.5v minimum across the limit resistor, with 1.0v or more being better. You won't get the segments to light reliably, much less be able to balance the current through them to get uniform brightness-- the brightness is proportional the current.


    Given this, I would suggest following the advice to use an integrated OLED display, if you can. If you want to go with the 7-seg units, there are a few options that I will outline:


    1) Use a pnp transistor in common emitter at the anodes with an npn to ground as a first gain stage from the MSP430 output. You will need current limiting resistors at the bases of the npn, and between the pnp bases and npn collectors.


    2) use a low drop LED current driver array instead of the uln2803, if you can find one with lower than 0.5V drop. Then you won't need limit resistors for the LED segments, as that will be done by the IC (using current mirrors internally).


    3) Use a higher drive voltage for the LEDs. This will require a little more work for the anode switching, but option1 will do the trick. Using this with option 1 lets you use a larger limit resistor for the LED segments, giving more uniform brightness. Note that the schematic on the page you linked to is for an arduino, which runs at 5V, thereby providing some margin for the current limit resistor.

  5. I have not tried Energia, but the test machine at work has had a number of issues with a variety of software. One of the students giuneapigged with Eclipse and had no end of trouble a few weeks ago, and ended up backing to win8. I don't know what the issue was, but I am not going to go to 10 for other reasons (license conditions among others)

  6. Needed a new board vise that would sit flat. The old linemaster is not quite the thing for some jobs, and is kinda a pain to crank, though it is real solid and heavy.


    This was out of the scrap bin in about an hour. 1/2" square tube, 1/4" rod, a spring from the junk pile, and a thumbscrew. Mots time consuming part was tapping the holes. No tools more advanced than a handheld drill and a hand tap and hand die (for the end of the rod). There is a nut inside the tube to jam with the nut on the rod end. I was trying to figure how to mill a tapered grip on a chunk of ABS from the scrap bucket, then I said to myself: "self, it is only going to be a taper edge to just grip the top of the board and hold it down. Why not give more room by using flat head (countersink) screws". So I did.


    Rubber baby buggy bumpers on the bottom for gription.


    Edit: fixing really embarrassing typos. Ok, I'm not really embarrassed... and adding pic holding board




  7. Your DIY microscope? I don't understand.

    DIY camera for the 'scope. The 'Scope itself is a Nikon stereo zoom I picked up for a gloatable low price, that has an oddball camera port. Two ports, one left and one right, but the optics for them are non-standard, so no way I can afford commercial cam optics. Best price I have found used is still over $1000, without a camera. This is trial run for a better quality and resolution setup.

  8. Well, finally woke back up, got real work done (one of the ways I make a living), and for those that are interested, have pics of the $3ish junkpile microscope cam. I did finally get the focus in in sync with the eyepieces. Just a real tight focal plane. If anyone wants pics and complete description, let me know. Otherwise, attached is a pic of the final product. And, yes, that is a handlebar clamp. The second time I pulled the camera off and had to try to re-align and find the focal plane, that went on to make it easy to find location. I was going to make up a shim to go between the registration faces in teh tube, but this is good enough, so I didn't bother.


  9. Since this thread is back to life:


    Right now, I am going to bed. Spent the night making a microscope camera from an old webcam. Optics from the defunct NTSC cam that came with the 'scope. Needed to set p so the optics form an image and mount the sensor of the cam in the image plane, while making it adjustable enough to align. Junk box to the rescue. Worked overnight because a) I started late afternoon, 2) it is useful to be able to turn on the dark, and iii) a lot of fit and fiddle with the lathe and waiting for epoxy to set up.


    Cam has such a small sensor that full frame is about 4mm low zoom, and about 400micron full zoom, versus 20+mm down to 2+mm via the eyepieces. This gives about 8micron per pixel to less than one. The resolving limit for the scope is about 2.5microns, so, as I knew going in, this is far from a perfect solution. I really want a larger sensor and better match for the optics, but can't beat the price. About $3 for a PVC pipe part and three nylon screws I didn't have in the junk box. The rest was on hand.


    Thing I can't figure out, and may have to do some actual thinking and reading about things I haven't dealt with in close to 30 years, is why the focus is rock solid in the eyepieces when zooming, but changes in the cam port. Shouldn't happen as the zoom stage is infinfite focus in and out and the cam port optical paths are supposed to be length matched. Unfortunately not my field, so, for the moment, I made my best compromise and will deal with it. The change is substantial: the focus in the eyepieces is with the objective roughly 100mm from the target, and the shift in the cam port is about 24mm over the zoom range. Should be maybe 1 or 2mm max.


    Pics if I remember when I wake up.

  10. Since this thread is resurrected, might as well mention what I did on my summer vacation:


    2452 was the processor of choice, as I had a few around. Someone with more money that reason was the client. A roughly 100 yr old power plant D'arsonval movement was the victim. A DS18B20 was the imperitus. Money in my pocket was the result. Eventually (when I finish the setup in my own house, since I got paid to do the work and marginal cost for me is scrap bin plus a little time) I will post. Not original concept, but ideal for the 2452.

  11. There really isn't much to it.


    In many contexts, it can get quite involved, but in a straightforward application on a small processor like the MSP430, you can keep it simple.


    Def (working): Semaphore: A signal made available by one function for to indicatte a status or condition to one or more other functions, outside the standard call-return or exception models.


    For your application, I would define an external (global; outside all functions) volatile (signal to the compiler that the variable can be changed from more than one place in an unsynchronized, unchecked, and independent manner, so that ANY access to the variable it via memory, not via temporary use of a processor register) integer that the interrupt handler sets to some value when a bit is complete, and the main loop watches to know when to prep the next bit.


    For example: the semaphore value might also act as the timer increment, and the main loop looks for it to be reset to 0

    // at header of code
    // outside any function
    volatile unsigned int nextbitcount=0;
    // ...
    // ...
    // ...
    // in main loop
    // ...
    // ...
    // wit for the interrupt routine to be done with bit
       while (nextbitcount) { // nextbitcount!=0
          } // not ready for new value
       if (dataval &0x0080) { // is MSb of current byte a 1?
           nextbitcount = 58;
       } else {
           nextbitcount = 100;
       dataval = (dataval <<1);; // shift to bring next bit to MSb
    // in interrupt handler
    // ...
    // ...
    // the bit being used for output is in var outputbitmask
    // if it is, for example, P1.5, outputbitmask is set by
    // #define outputbitmask 0x20
       P1OUT ^= outputbitmask; // flip output bit
       CCR1 += nextbitcount; // time for next interrupt
       if (P1OUT & outputbitmask) { // was output set to high? lots of ways to test this
          // in second half cycle... time to update in main loop
          nextbitcount=0; // reset semaphore

    This is not finished code, obviously. Note that there are three  parts: the external var that does double duty-- semaphore to signal condition to main and also communicates the data timing from main to the interrupt handler;the synch loop and bit handler in main (which is at best a model, as the main loop is unlikely to be be locked in a wait like this if it also needs to gather inputs, like throttle position, and sequence the data bytes and sync bits between them...but this is a model), and the interrupt handler, which may actually be pretty much written for you here.


    This is a common model, and is used for a wide variety of tasks, including completely independent functions, such as when one interrupt handler needs to talk to another or two unsynchronized threads need to signal each other, though this is about the simplest application, and more by the time you get to multithreaded cases (not happening on the low end MSP430 in all likelyhood, but common in full operating systems like *nix) the signalling is generally done using a more involved library tool.

  12. Looking at the standard on the NMRA site (S-9.1 - http://www.nmra.org/sites/default/files/standards/sandrp/pdf/s-9.1_electrical_standards_2006.pdf), the timing isn't terribly tight.


    If I were going to implement this, I'd use a single timerA and deal with the outputs in an  interrupt handler. Let the timer free run in continuous, and use CCR1 to set the interrupt time. Each entry to the interrupt, add the appropriate time to CCR1 and change the state of the output as appropriate. There are a number of ways to sequence the bits. I would probably not do it in the interrupt routine. I would use a semaphore to signal the main loop to prep the next bit, and place the value in a shared volatile.


    I would run the timer from MCLK, and pretty much any calibrated speed would be fine for this... the timing is really not that tight (52-64us for each half of a `1' pulse) 8MHz clock is MORE than adequate, and 1MHz might even be OK, though the interrupt latency variability might make it sketchy for a receiver that isn't real tolerant. The `0' bits are so loose that timing for them isn't an issue (95 to 9900us for each half cycle, total less than 12000us) This is a perfect application for software handling of the data. For the 8MHz clock, I would set the timer to divide by 8, so it counts microseconds. Interrupt latency will be less than 3/4us (six processor clocks).


    There are a number of standard samples showing the basic idea for using the interrupts this way, such as Example 1 in http://www.ccs.neu.edu/home/noubir/Courses/SWARM/S09/slides/msp430-clocks-timers.pdfor on pages23/24 of https://courses.cs.washington.edu/courses/cse466/11au/calendar/04-Interrupts-posted.pdf


    A number of the timer examples in the TI MSP430 documents also use the same model.

  13. Never had a need to look at the one-bit level shifters before. handy little buggers, they appear to be. Ordered a couple different flavours to play with.


    In the mean time, what I have is not quite making sense, and I figure I am missing something in the documentation. What I am seeing is that, if I set REFOUT in the ADC10CTL register, while the appropriate ADC10AE bit is not set, the output hangs at a stiff 750mV rather than being pulled low as the P1OUT bit specifies. Doesn't even float. It is stiff against 500uA. My initial thought was modulate the ADC10AE bit to switch between the P1.4 output value and the reference. Instread, I need to also modulate REFOUTT in the control register.


    This is two kinds of ugly: 1) the code is kludgy, and 2) when going high (switching the pin to analog and enebling REFOUT), there is a roughly 1us spike to Vcc, and the output hangs at 750mV for the time between the two operations (about 5us at the default 1MHz clock) due to the lack of synch. The weirdest part is that if I swap the order of the state assignments so that the hang is on the falling edge, the output actually goes just about to zero before going back up to 750mV, holds there for 5us, then the second part of the state is set and to ground it goes.


    Does issue 2) cause a real problem? no. The energy in the spike and in the 750mV hang is too low to have an effect on the analog movement being driven. But, aesthetically, it bugs me.


    Hence, my asking...



    BTW, this just cycles from bottom to top of range to test the analog movement.

     * Software PWM on p1.4 using the internal voltage ref as high
    /* led's port 0, bits 0 and 6 */
    #define led1 0x01
    #define button 0x08 /* launchpad pushbutton bit 3 */
    #define PWM_CYCLE_TIME 0x8000       /* approx 1/30 sec */
    #define PERIOD (0x0080) /* PWM interrupt period */ /* was 0x0100 */
    #define PWM_CYCLE (PWM_CYCLE_TIME/PERIOD) /* number of periods per cycle */
    volatile unsigned int cycleflag=0; // flag for start of new PWM cycle
    volatile unsigned int period=PWM_CYCLE; // period counter for PWM cycles
    volatile unsigned int PW=1;    // current output pulse width
    #define PWM_ONE   (SREF_1 | REFON | REFOUT) /* reference is on at 1.5V and ADC select is for internal ref, set p1.4 to ref voltage */
    #define PWM_ZERO  (SREF_1 | REFON) /* reference is on at 1.5V and ADC select is for internal ref, set p1.4 to ref voltage */
    volatile unsigned int nextout=0;
    volatile unsigned int nextADC=PWM_ZERO;
     * main.c
    int main(void) {
        WDTCTL = WDTPW | WDTHOLD;	// Stop watchdog timer
        // clock default ~1MHZ
        P1DIR = ~(button); //  P1.x all outputs except pushbutton
        P1OUT=button;       //  setup for pushbutton to be input, all other P1 are low
        // to minimize issues with floating I/O
        P2DIR |= 0xff;// P2 all out
        P2OUT =0;
        // set up timer
        // USE MCLK at 1MHz (default)
        CCR0 = PERIOD; // period
        TACTL = MC_1|TASSEL_2|TACLR;    // set up timer
        		//MC_1: up mode    TACLR: reset counter to 0   TASSEL_2: source SMCLK
        CCTL0 = CCIE; // enable interrupt for timer on compare 0; interrupt on final count
        _BIS_SR( GIE); // enable interrupt
        unsigned int lifectr=0;
        while (1) {
          if (!(P1IN & button)) { //
        	  PW=PWM_CYCLE; // full on
        	  continue; // do no PWM calcs
          if (cycleflag) { // calculate new cycle
            cycleflag = 0; // indicate cycle detected
            if (lifectr++ & 0x80) {P1OUT|=led1;} else {P1OUT &= ~(led1);} // flash led1 periodically
            if (PW>=PWM_CYCLE) {PW=0;}
          } // if cycleflag
        } // while inf loop
    //Timer A0 interrupt svc routine
    #pragma vector=TIMER0_A0_VECTOR
    __interrupt void Timer_A (void)
    	// output the new state. Doing it here, at the interrupt time, gives decent synchronization
            // either order spikes on rise, but this order hangs on rise, the other order hangs on fall
            ADC10AE0=nextout; // set bits with analog enable
    	if (--period ==0) { period = PWM_CYCLE; cycleflag=1;  } // count off this interval; if new cycle, flag for main
    	if (period < PW) { // set next state
                    nextout=0x10;  // 0x10
    	} else{
    } // interrupt handlerTIMER_A
  14. Using a g2553:


    Any suggestions for doing PWM using the internal reference for the high so that Vcc doesn't need to be regulated? Battery powered application so not using a regulator is desirable.


    Only way I can come up with is use P1.4 as the PWM output, after setting up the reference, toggling ADC10AE.4 in software, otherwise configuring the pin for output and a value of 0. It works, but it is kinda ugly, so a more elegant solution would be nice.


    The application is driving an analog meter movement, so the current is in the ballpark of 200uA full scale.

  15. Code is attached to the post in the halloween contest thread. Take a look at that first (about halfway down.. the file is "main_revised.c") Note principally the setup at the start of main, and the timer interrupt service function. The interrupt function outputs new state, then counts clock ticks. At the end of PWM cycle, it resets the counters for a new cycle, loads PWM values for then new cycle, and raises a flag for the main to update the PWM values for the next cycle to follow. Note that the first thing done is update the outputs. This minimizes jitter. Not as good as hardware PWM, but close.

  16. You followed up while I was typing.


    Using the tip31c will require a different setup to drive it, as they are relatively low current gain. Darlington using a 2n3904 for the first stage will do fine.


    Also, you CAN do more than one PWM, even on the most basic MSP430g devices. The 'g2452 has two hardware driven outputs for the single timer_A (each of which can be one more than one pin), for example. Other higher level devices allow more hardware PWM.


    That said, using software, you can do as man as you want. Somewhere in the past ( http://forum.43oh.com/topic/4511-ended-oct-2013-43oh-halloween-contest/) I have a project that does 8 PWM for a similar purpose. Not quite the resolution of hardware PWM, but does a dandy job for many things.


    edit: typo in part number

  17. Absolutely. The style of strip you are using is about the easiest to control.


    Without getting into details of what you did (since you didn't provide the code, say what processor you are using, etc), I'll go over a few things related.


    Assuming that you understand how PWM works, the key questions are polarity for the drive (is the LED on when the output is high? or when it is low? The adafruit sample should be on when high), what gate voltage is needed to enable the MOSFET (assuming you are using the same device as the tutorial), what pins can you use for PWM, and are the outputs properly set for PWM. There are other things to look at, but these come to mind first, as they are all relevant to the difference between a 5V AMTEL processor and a 3.3 (or 3.6)V MP430


    I can't address the last two questions without seeing the code you used and knowing the processor you are running on, but the second may be key: The STP16NF06 drain current is essentially 0 until Vgs exceeds 3.6V (see fig6, P6/14 of http://www.st.com/web/en/resource/technical/document/datasheet/CD00002501.pdf) Without some gate voltage boost, the MOSFET won't turn on. This isn't an issue with a 5V processor, as at 5V Vgs, drain current is approx 8A, if Vds is sufficient.


    I would suggest a level shifter to drive the gate if you want to use this MOSFET, or changing to a bipolar driver. I have used an assortment of methods over the years, but the easiest is something like a ULN2803 or similar. It isn't that hard to cob up a level shifter to drive the gate of the MOSFET with an npn small signal transistor and resistor, though that will invert the polarity of the drive signal, which you can compensate for in software. You can also use one of the many 74HCT devices as a level shifter. The inputs are comaptable with the 3.3 or 3.6V outputs of hte MSP430 (actually, down to about 2.5V reliably) when powered by 5V.

  18. I generally use a transistor array or LED constant current sink driver and run a matrix common cathode, using the microcontroller outputs for the anode drive. One of the go-to arrays I use is uln2804 (darlington array).


    Unfortunately, few microcontrollers have the ability to either source or sink enough current to drive an array at significant brightness without external drivers.

  19. I will freely admit that I am still a DIP guy. Several reasons: I'v been around a long time so familiarity is a piece; I can see a DIP without the microscope; Most of what I do anymore is personal or for teaching, and being able to pop a 2553 or 2452 or.. into  breadboard with a small cap an a resistor and nothing else, rather than make up a PC board, is a big benefit.

  • Create New...