Jump to content
43oh

jsolarski

Members
  • Content Count

    568
  • Joined

  • Last visited

  • Days Won

    8

Reputation Activity

  1. Like
    jsolarski reacted to MarkoeZ in 2 Questions on how to use the MSP430g2252 the best way   
    Ok, just in case someone ends up here in a search:
    I solved this by using the Watchdog Timer for the PWM using jsolarski's code, from this page: http://justinstech.org/2010/10/msp430-interrupt-driven-pwm/
     
    Full description here: http://markoez.pirategames.co.uk/index.php/blog/msp430-serial-pwm-using-one-timer-and-wdt/
     
    Cheers!
  2. Like
    jsolarski reacted to amstan in MSPGCC support for newer Value Line parts?   
    There's ubuntu packages available. You might still have to compile some things from source(ex: the mspdebug from there can't do fr boards yet).
  3. Like
    jsolarski reacted to zeke in anyone notice digi's new wifi module yet?   
    Has anyone noticed digi's new wifi module product yet?
     
    Apparently, it's only $49 and it has the same footprint as their zigbee module.
     
    Kinda makes me wonder where I could make use of one. Hmmm... :think:
  4. Like
    jsolarski reacted to ERTW in Free MAXADCLite EV Kit - OUT OF STOCK   
    -----------------------------------------------------------------------------------------------------------------------------
    Update: Apparently the samples are out of stock, even though it doesn't mention it on the Maxim website.
    -----------------------------------------------------------------------------------------------------------------------------
     
    Saw this over on Dangerous Prototypes but figured I'd post it here as well. Apparently this was posted in April and there are 1000 available, but I ordered one today. You do unfortunately need a business or educational institution e-mail to be able to order one.
     
    http://www.maxim-ic.com/landing/?lpk=585
     
    This versatile EV kit allows you to measure any analog signal source directly from your computer. Just download the MAXADCLite GUI software (PC only), connect your analog input signal, and start measuring. (Power is provided through the USB port.)
     
    Key Benefits
     
    * Smallest 12-bit SAR ADC
    o 2 channels
    o Integrated reference
    o 1.9mm x 2.2mm package
    * Lowest system cost
    o Integrated multiplexer, FIFO, and sequencer
    o Same price as competitive stand alone ADCs
    * Ultra-low power
    o Active: 2
  5. Like
    jsolarski reacted to gwdeveloper in One last BMP085 Project...   
    Ok, so the MSP-EXP430F5529 dev board may not provide me with optimal hardware I/O for my greenhouse controller. Basically, I'd want the power/speed of the F5529 without the accelerometer. If I were rebuilding this board, I'd move the LCD SPI over to UCA1 and free up UCB1 for an I2C channel. UCB0 is being used for the RF2500t interface. So...
     
    My solution (for now) is to use a standalone G2553 as an I2C to UART translator. It actually works out well but not my optimal hardware configuration. This project may not be useful for many but some might find bits of the code helpful. The kicker, though, is I configured all of the hardware using Grace. :crazy:
     
    If you have a BMP085, you can open a terminal on your launchpad port and receive temperature and barometric pressure.
     

    /****************************************************************/ /* Greg Whitmore */ /* greg@gwdeveloper.net */ /* www.gwdeveloper.net */ /****************************************************************/ /* released under the "Use at your own risk" license */ /* use it how you want, where you want and have fun */ /* debugging the code. */ /* MSP-EXP430G2553 */ /****************************************************************/ /* includes */ #include #include #include #include "itoa.h" /* bmp085 defines */ #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 */ // bmp085 void bmp085_cal(void); unsigned int bmp085_ut(void); unsigned long bmp085_up(void); void get_bmp085(void); // iic void iic_init(void); void iic_tx_init(void); void iic_rx_init(void); void start_TX(void); void start_RX(void); int sendByte_getBytes(unsigned char reg_2_read, int bytes_to_rx); //uart void TXString( char* string, int length ); /* variables */ // bmp085 // 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; // adjusters long b6Temp; long x1Temp; //unsigned int i; unsigned char temp_buffer[8]; unsigned char pres_buffer[8]; // 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 }; // iic 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 void main(void) { CSL_init(); // Activate Grace-generated configuration __enable_interrupt(); // Set global interrupt enable bmp085_cal(); // load calibration data get_bmp085(); // loop to collect temp & pressure // and TX via UART } // store PROM data into usable variables void bmp085_cal(void) { ac1 = sendByte_getBytes(0xAA, 2); __delay_cycles(1000); ac2 = sendByte_getBytes(0xAC, 2); __delay_cycles(1000); ac3 = sendByte_getBytes(0xAE, 2); __delay_cycles(1000); ac4 = sendByte_getBytes(0xB0, 2); __delay_cycles(1000); ac5 = sendByte_getBytes(0xB2, 2); __delay_cycles(1000); ac6 = sendByte_getBytes(0xB4, 2); __delay_cycles(1000); b1 = sendByte_getBytes(0xB6, 2); __delay_cycles(1000); b2 = sendByte_getBytes(0xB8, 2); __delay_cycles(1000); mb = sendByte_getBytes(0xBA, 2); __delay_cycles(1000); mc = sendByte_getBytes(0xBC, 2); __delay_cycles(1000); md = sendByte_getBytes(0xBE, 2); __delay_cycles(1000); } // read uncompensated temperature and return msb & lsb unsigned int bmp085_ut(void) { iic_tx_init(); __delay_cycles(1000); PTxData = (unsigned char *)utTxData; // send control reg and temp reg TXByteCtr = 2; // Load TX byte counter start_TX(); __delay_cycles(200000); // long delay here or it hangs on the valueline mcus return (sendByte_getBytes(BMP085_MSB_REG, 2)); } // read uncompensated pressure and return msb, lsb & xlsb unsigned long bmp085_up(void) { iic_tx_init(); __delay_cycles(1000); PTxData = (unsigned char *)upTxData; // send control reg and temp reg TXByteCtr = 2; // Load TX byte counter start_TX(); __delay_cycles(200000); // long delay here or it hangs on the valueline mcus PTxData = (unsigned char *)msbData; // send msb read register TXByteCtr = 1; start_TX(); iic_rx_init(); // set RX interrupt __delay_cycles(200000); // long delay here or it hangs on the valueline mcus 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 // sendByte_getBytes not used here due to long shifts return ( (( (long)RxBuffer[0] << 16) | ( (long)RxBuffer[1] << 8) | (long)RxBuffer[2]) >> 8); } // collect uncompensated temp and pressure // calculate compensated temp and pressure then transmit via UART void get_bmp085() { while (1){ 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 // calc true pressure b6 = b5 - 4000; //x1 = (b2 * (b6 * b6) >> 12) >> 11; // won't work this way on the value line LSR_23 error b6Temp = b6 * b6; x1Temp = b2 * b6Temp; x1Temp = x1Temp >> 12; x1 = x1Temp >> 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; 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); TXString((char*)temp_buffer, sizeof temp_buffer); TXString("\r\n", 2); TXString((char*)pres_buffer, sizeof pres_buffer); TXString("\r\n", 2); __delay_cycles(500000); } } void iic_tx_init() { UCB0I2CSA = BMP085_ADDR; UCB0I2CIE |= UCB0TXIE; // Enable TX interrupt } void iic_rx_init(void) { UCB0I2CIE |= UCB0RXIE; // enable RX interrupt } // send 1 byte, return 2 bytes - needs the return expanded for X bytes int sendByte_getBytes(unsigned char reg_2_read, int bytes_to_rx) { // transmit slave address and register to read iic_tx_init(); __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 } // iic 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 } // iic 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); } // interrupt pragma is defined in grace void iic_TX_isr(void) { if (TXByteCtr) // Check TX byte counter { UCB0TXBUF = *PTxData++; // Load TX buffer TXByteCtr--; // Decrement TX byte counter } else { UCB0CTL1 |= UCTXSTP; // I2C stop condition IFG2 &= ~UCB0TXIFG; // Clear USCI_B0 TX int flag } } // interrupt pragma is defined in grace void iic_RX_isr(void) { RXByteCtr--; // Decrement RX byte counter if (RXByteCtr) { P1OUT ^= 0x10; *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 } } // tx function borrowed from TI's virtual_com_cmds.c void TXString( char* string, int length ) { int pointer; for( pointer = 0; pointer < length; pointer++) { volatile int i; UCA0TXBUF = string[pointer]; while (!(IFG2&UCA0TXIFG)); // USCI_A0 TX buffer ready? } } // timer A isr is simply toggling activity light for now. // future pwm functions to go here void timer_A_ISR(void) { P1OUT ^= BIT0; }
  6. Like
    jsolarski reacted to MarkoeZ in New MSP430 Launchpad Booster Packs   
    Hello Guys and Girls,
     
    Have not seen any mention of these on the forum: Some weeks ago there were a couple of energy harvesting booster packs released for the MSP430 Launchpad, and even more recent a User Interface booster pack.
     
    Check the 43oh blog http://www.43oh.com or the TI Launchpad Site for more info.http://e2e.ti.com/group/msp430launchpad/b/boosterpacks/default.aspx
     
    Cheers!
     
    MarkoeZ
  7. Like
    jsolarski reacted to gordon in SD16 Help   
    For others' reference, as I told jsolarski, I strongly believe -mendup-at=main should not ever be used. There's room for a nasty surprise if, for example, your setup code runs again when you don't expect it.
  8. Like
    jsolarski reacted to gordon in Makefile for MSPGCC   
    Following up on viewtopic.php?f=10&t=1228#p8163, I made some tweaks to the Makefile. It now has simple heuristics to detect whether you are running Windows (I'm not much of a Windows person, so it is kind of a shot in the dark, please test), and if yes, it uses MSP430Flasher for installing.
     
    It is also possible to have only one central instance of this "master" Makefile, with per-project Makefiles only referencing this one, possibly overriding some settings.
     
    Per-project Makefile:

    TARGETMCU := msp430g2211 include ../Makefile
    (I really don't recommend symlinking the master Makefile in project directories, you'll surely shoot yourself in the foot sooner or later.)
     
    Master Makefile:

    TARGETMCU ?= msp430g2231 SRCS ?= main.c CROSS := msp430- CC := $(CROSS)gcc CXX := $(CROSS)g++ OBJDUMP := $(CROSS)objdump OBJCOPY := $(CROSS)objcopy SIZE := $(CROSS)size LD := $(CC) MSPDEBUG := mspdebug MSP430FLASHER := C:\\bin\\MSP430Flasher LDFLAGS := -mmcu=$(TARGETMCU) CFLAGS := -Os -Wall -W -Wextra -Werror -std=gnu99 -g -mmcu=$(TARGETMCU) ifneq ($(WITH_CXX),) CC := $(CXX) LD := $(CC) endif ifeq ($(WITH_CXX),) CFLAGS += -Wstrict-prototypes -Wmissing-prototypes -Wbad-function-cast CFLAGS += -Werror-implicit-function-declaration -Wdeclaration-after-statement CFLAGS += -Wnested-externs -Wold-style-definition endif CFLAGS += -Wmissing-declarations -Winit-self -Winline -Wredundant-decls CFLAGS += -Wshadow -Wpointer-arith -Wcast-qual -Wsign-compare -Wformat=2 CFLAGS += -Wfloat-equal -Wmissing-field-initializers CFLAGS += -Wmissing-include-dirs -Wswitch-default -Wpacked CFLAGS += -Wpacked -Wlarger-than-65500 -Wunknown-pragmas CFLAGS += -Wmissing-format-attribute -Wmissing-noreturn CFLAGS += -Wstrict-aliasing=2 -Wswitch-enum -Wundef -Wunreachable-code CFLAGS += -Wunsafe-loop-optimizations -Wwrite-strings -Wcast-align CFLAGS += -Wformat-nonliteral -Wformat-security -Waggregate-return CFLAGS += -fno-common -Wp,-D_FORTIFY_SOURCE=2 CFLAGS += -finline-functions CXXFLAGS := $(CFLAGS) PROG := $(firstword $(SRCS:.c=)) OBJS := $(SRCS:.c=.o) all: $(PROG).elf $(PROG).hex $(PROG).lst %.elf: $(OBJS) $(LD) $(LDFLAGS) -o $(PROG).elf $(OBJS) $(SIZE) $< %.o: %.c $(CC) $(CFLAGS) -c $< %.lst: %.elf $(OBJDUMP) -DS $< > $@ %.hex: %.elf $(OBJCOPY) -O ihex $< $@ clean: -rm -f $(PROG).elf $(PROG).lst $(PROG).hex $(OBJS) install: $(PROG).elf $(PROG).hex ifeq ($(OS),Windows_NT) $(MSP430FLASHER) -n $(TARGETMCU) -e ERASE_MAIN -w $< else $(MSPDEBUG) -n rf2500 "prog $<" endif erase: $(MSPDEBUG) -n rf2500 erase .PHONY: all clean install erase .PRECIOUS: %.o
     
    I don't know what options does MSP430Flasher take, I just sort of guessed.
  9. Like
    jsolarski reacted to gwdeveloper in Greenhouse   
    There have been a few questions about my greenhouse so I thought I'd post some info and pictures here. I couldn't find a kit or plans that matched dimensions I wanted. Our backyard sees seasonal 50+mph winds so the greenhouse needed to be sturdy. Previous attempts with pvc construction were destroyed in weeks.
     
     
    Greenhouse Specifications:
    8' x 8' x 8' (peak of roof)
    Wood structure, paint for sealant
    Polycarbonate "Tufftex" panels with 90% light transmission
    Decomposed granite floor (high silicon dioxide, to work as a thermal sink)
    Passive radiant floor heating using solar collector (PEX tubing with 3/4" foam-core, aluminum reflective barrier)
    GWDeveloper Urban Greenhouse Controller
     
    Urban Greenhouse Controller
    Plug-and-play operation using onsite ET data
    Configurable Sensor Array
    Humidity
    Temperature
    Barometric pressure
    Wind direction & speed
    Daylight collected
    pH & EC
    Vent and door positions
    Water flow rate
    Hardware Control
    Vents
    Exhaust Fans
    Misters
    Irrigation
    Aquaponics
    User Input
    Touchscreen display in greenhouse
    Web accesible controls via wireless access point
     
    If anyone wants free plans for a sturdy, 8'x8'x8' greenhouse, let me know. My parents are looking into purchasing my neighbors house for us to use as a commercial kitchen and expansion of the gardens so another greenhouse or 2 will be built there as well.
  10. Like
    jsolarski got a reaction from pine in Connecting two LaunchPads   
    Yes in the TI code examples there are both SPI and I2C examples
     
     
    they are very lame, but they do give you a good starting point
     

    //****************************************************************************** // MSP430F20x2/3 Demo - SPI full-Duplex 3-wire Master // // Description: SPI Master communicates full-duplex with SPI Slave using // 3-wire mode. The level on P1.4 is TX'ed and RX'ed to P1.0. // Master will pulse slave reset for synch start. // ACLK = n/a, MCLK = SMCLK = Default DCO // // Slave Master // MSP430F20x2/3 MSP430F20x2/3 // ----------------- ----------------- // | XIN|- /|\| XIN|- // | | | | | // | XOUT|- --|RST XOUT|- // | | /|\ | | // | RST/NMI|--+<----|P1.2 | // LED <-|P1.0 | | P1.4|<- // ->|P1.4 | | P1.0|-> LED // | SDI/P1.7|<-------|P1.6/SDO | // | SDO/P1.6|------->|P1.7/SDI | // | SCLK/P1.5|<-------|P1.5/SCLK | // // M. Buccini / L. Westlund // Texas Instruments Inc. // October 2005 // Built with CCE Version: 3.2.0 and IAR Embedded Workbench Version: 3.40A //****************************************************************************** #include void main(void) { volatile unsigned int i; WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer P1OUT = 0x10; // P1.4 set, else reset P1REN |= 0x10; // P1.4 pullup P1DIR = 0x01; // P1.0 output, else input USICTL0 |= USIPE7 + USIPE6 + USIPE5 + USIMST + USIOE; // Port, SPI master USICTL1 |= USIIE; // Counter interrupt, flag remains set USICKCTL = USIDIV_4 + USISSEL_2; // /16 SMCLK USICTL0 &= ~USISWRST; // USI released for operation USISRL = P1IN; // init-load data P1DIR |= 0x04; // Reset Slave P1DIR &= ~0x04; for (i = 0xFFF; i > 0; i--); // Time for slave to ready USICNT = 8; // init-load counter _BIS_SR(LPM0_bits + GIE); // Enter LPM0 w/ interrupt } // USI interrupt service routine #pragma vector=USI_VECTOR __interrupt void universal_serial_interface(void) { if (0x10 & USISRL) P1OUT |= 0x01; else P1OUT &= ~0x01; USISRL = P1IN; USICNT = 8; // re-load counter }
     
     
    and
     

    //****************************************************************************** // MSP430F20x2/3 Demo - SPI full-Duplex 3-wire Slave // // Description: SPI Master communicates full-duplex with SPI Slave using // 3-wire mode. The level on P1.4 is TX'ed and RX'ed to P1.0. // Master will pulse slave reset for synch start. // ACLK = n/a, MCLK = SMCLK = Default DCO // // Slave Master // MSP430F20x2/3 MSP430F20x2/3 // ----------------- ----------------- // | XIN|- /|\| XIN|- // | | | | | // | XOUT|- --|RST XOUT|- // | | /|\ | | // | RST/NMI|--+<----|P1.2 | // LED <-|P1.0 | | P1.4|<- // ->|P1.4 | | P1.0|-> LED // | SDI/P1.7|<-------|P1.6/SDO | // | SDO/P1.6|------->|P1.7/SDI | // | SCLK/P1.5|<-------|P1.5/SCLK | // // M. Buccini / L. Westlund // Texas Instruments Inc. // October 2005 // Built with CCE Version: 3.2.0 and IAR Embedded Workbench Version: 3.40A //****************************************************************************** #include void main(void) { WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer P1OUT = 0x10; // P1.4 set, else reset P1REN |= 0x10; // P1.4 pullup P1DIR = 0x01; // P1.0 output, else input USICTL0 |= USIPE7 + USIPE6 + USIPE5 + USIOE; // Port, SPI slave USICTL1 |= USIIE; // Counter interrupt, flag remains set USICTL0 &= ~USISWRST; // USI released for operation USISRL = P1IN; // init-load data USICNT = 8; // init-load counter _BIS_SR(LPM0_bits + GIE); // Enter LPM0 w/ interrupt } // USI interrupt service routine #pragma vector=USI_VECTOR __interrupt void universal_serial_interface(void) { if (0x10 & USISRL) P1OUT |= 0x01; else P1OUT &= ~0x01; USISRL = P1IN; USICNT = 8; // re-load counter }
     
     
    to ad a token you would have to modify the code, but should be straight forward.
  11. Like
    jsolarski reacted to longhorn engineer in MSP-EXP430 : Accelerometer and Servo Demo   
    Just finished tweaking and streaming the code.
     
    This code also contains a twin servo routine. The servos are connected to P1.4 and P1.5. When the X-axis moves the servo on P1.4 moves and when the Y-axis moves the servo on P1.5. The Z-aixs is implemented but not used in the program.
     

    #include "msp430fr5739.h" #include "FR_EXP.h" #define SERVO_1 BIT4 #define SERVO_2 BIT5 #define scale 9 unsigned int servo_counter = 0; unsigned int servo1pos = 1500; unsigned int servo2pos = 1500; unsigned int ADC_counter = 0; unsigned int ADCResult_X, ADCResult_Y, ADCResult_Z; unsigned int CalValue_X, CalValue_Y, CalValue_Z; unsigned int temp; void main(void) { WDTCTL = WDTPW + WDTHOLD; //Stop the dog SystemInit(); //Setup the pins StartUpSequence(); //Copy Ti's fancy LED boot up trick SetupAccel(); //Setup the ADC and Accel CalibrateADC(); //Find zero points of all 3 axis ADC10CTL0 |= ADC10ENC | ADC10SC; //Start the first sample. If this is not done the ADC10 interupt will not trigger. while (1) { if (ADCResult_X > CalValue_X + 10) { servo1pos = 1500 + scale * (ADCResult_X - CalValue_X); if (servo1pos > 2500) { servo1pos = 2500; } } else if (ADCResult_X < CalValue_X - 10) { servo1pos = 1500 - scale * (CalValue_X - ADCResult_X); if (servo1pos < 500) { servo1pos = 500; } } else { servo1pos = 1500; } if (ADCResult_Y > CalValue_Y + 10) { servo2pos = 1500 + scale * (ADCResult_Y - CalValue_Y); if (servo2pos > 2500) { servo2pos = 2500; } } else if (ADCResult_Y < CalValue_Y - 10) { servo2pos = 1500 - scale * (CalValue_Y - ADCResult_Y); if (servo2pos < 500) { servo2pos = 500; } } else { servo2pos = 1500; } } } void SystemInit(void) //Sets up the Fraunch board for Accel reads and LED tricks { //Startup clock system in max. DCO setting ~8MHz // This value is closer to 10MHz on untrimmed parts CSCTL0_H = 0xA5; // Unlock register CSCTL1 |= DCOFSEL0 + DCOFSEL1; // Set max. DCO setting CSCTL2 = SELA_1 + SELS_3 + SELM_3; // set ACLK = vlo; MCLK = DCO CSCTL3 = DIVA_0 + DIVS_0 + DIVM_0; // set all dividers CSCTL0_H = 0x01; // Lock Register // Turn off temp. REFCTL0 |= REFTCOFF; REFCTL0 &= ~REFON; // Enable LEDs P3OUT &= ~(BIT6+BIT7+BIT5+BIT4); P3DIR |= BIT6+BIT7+BIT5+BIT4; PJOUT &= ~(BIT0+BIT1+BIT2+BIT3); PJDIR |= BIT0 +BIT1+BIT2+BIT3; // P3.0,P3.1 and P3.2 are accelerometer inputs P3OUT &= ~(BIT0 + BIT1 + BIT2); P3DIR &= ~(BIT0 + BIT1 + BIT2); P3REN |= BIT0 + BIT1 + BIT2; // Setup Servo ports P1OUT &= ~(SERVO_1 + SERVO_2); P1DIR |= SERVO_1 + SERVO_2; P1SEL0 &= ~(SERVO_1 + SERVO_2); P1SEL1 &= ~(SERVO_1 + SERVO_2); // Setup Servo Interrupt TA0CCTL0 = CCIE; TA0CCR0 = 1500; TA0CTL = TASSEL_2 + MC_1 + ID_3; } void CalibrateADC(void) //Sets the "zero" point of the accelerometer { unsigned char CalibCounter =0; unsigned int Value = 0; __disable_interrupt(); //Turn off any interupts just incase ADC10CTL0 &= ~ADC10ENC; //Toggle ENC bit. Need this to change the ADC10INCH_x value. ADC10MCTL0 = ADC10SREF_0 + ADC10INCH_12; //Sample the X-axis while(CalibCounter <50) { P3OUT ^= BIT4; CalibCounter++; ADC10CTL0 |= ADC10ENC | ADC10SC; //Start sample. while (ADC10CTL1 & BUSY); //Wait for sample to be done. Value += ADC10MEM0; } CalValue_X = Value/50; //Average all samples to find the best zero. ADC10CTL0 &= ~ADC10ENC; //Toggle ENC bit. Need this to change the ADC10INCH_x value. CalibCounter = 0; //Reset the counters Value = 0; ADC10MCTL0 = ADC10SREF_0 + ADC10INCH_13; //Sample the Y-axis while(CalibCounter <50) { P3OUT ^= BIT4; CalibCounter++; ADC10CTL0 |= ADC10ENC | ADC10SC; //Start sample. while (ADC10CTL1 & BUSY); //Wait for sample to be done. Value += ADC10MEM0; } CalValue_Y = Value/50; //Average all samples to find the best zero. ADC10CTL0 &= ~ADC10ENC; //Toggle ENC bit. Need this to change the ADC10INCH_x value. CalibCounter = 0; //Reset the counters Value = 0; ADC10MCTL0 = ADC10SREF_0 + ADC10INCH_14; //Sampel the Z-axis while(CalibCounter <50) { P3OUT ^= BIT4; CalibCounter++; ADC10CTL0 |= ADC10ENC | ADC10SC; //Start sample. while (ADC10CTL1 & BUSY); //Wait for sample to be done. Value += ADC10MEM0; } CalValue_Z = Value/50; //Average all samples to find the best zero. ADC10CTL0 &= ~ADC10ENC; //Toggle ENC bit. Need this to change the ADC10INCH_x value. ADC10MCTL0 = ADC10SREF_0 + ADC10INCH_12; //We need to start at the X-axis first due to how the interupt routine works. __enable_interrupt(); //enable interupts } void SetupAccel(void) { //Setup accelerometer // ~20KHz sampling //Configure GPIO ACC_PORT_SEL0 |= ACC_X_PIN + ACC_Y_PIN + ACC_Z_PIN; //Enable A/D channel inputs ACC_PORT_SEL1 |= ACC_X_PIN + ACC_Y_PIN + ACC_Z_PIN; ACC_PORT_DIR &= ~(ACC_X_PIN + ACC_Y_PIN + ACC_Z_PIN); ACC_PWR_PORT_DIR |= ACC_PWR_PIN; //Enable ACC_POWER ACC_PWR_PORT_OUT |= ACC_PWR_PIN; // Allow the accelerometer to settle before sampling any data __delay_cycles(200000); //Setting up the ADC stuff ADC10CTL0 &= ~ADC10ENC; // Ensure ENC is clear ADC10CTL0 = ADC10ON + ADC10SHT_5; ADC10CTL1 = ADC10SHS_0 + ADC10SHP + ADC10CONSEQ_0 + ADC10SSEL_0; ADC10CTL2 = ADC10RES; ADC10MCTL0 = ADC10SREF_0 + ADC10INCH_12; ADC10IV = 0x00; //Clear all ADC12 channel int flags ADC10IE |= ADC10IE0; //Enable ADC10 interrupts __enable_interrupt(); } void StartUpSequence(void) //this is copied from the Ti Fraunch Pad experience. Only thing it does is make a fancy LED sequence on boot. { unsigned char flag=4,up=1,counter = 0; unsigned char LED_ArrayPJ[] = {0x01,0x02,0x04,0x08}; unsigned char LED_ArrayP3[] = {0x80,0x40,0x20,0x10}; while (counter <10) { counter++; PJOUT &= ~(BIT0 +BIT1+BIT2+BIT3); P3OUT &= ~(BIT4 +BIT5+BIT6+BIT7); if(up) { while(flag) { P3OUT = LED_ArrayP3[flag-1]; PJOUT = LED_ArrayPJ[flag-1]; LongDelay(); flag--; } up=0; } else { while(flag<4) { P3OUT = LED_ArrayP3[flag]; PJOUT = LED_ArrayPJ[flag]; LongDelay(); flag++; } up = 1; } } PJOUT &= ~(BIT0 +BIT1+BIT2+BIT3); P3OUT &= ~(BIT4 +BIT5+BIT6+BIT7); } void LongDelay() { __delay_cycles(250000); } //Servo Interrupt #pragma vector = TIMER0_A0_VECTOR __interrupt void Timer_A (void) { if(servo_counter == 0) { P1OUT |= SERVO_1; P1OUT |= SERVO_2; if (servo1pos >= servo2pos) { TA0CCR0 = servo2pos; } else { TA0CCR0 = servo1pos; } servo_counter++; } else if(servo_counter == 1) { if (servo1pos >= servo2pos) { P1OUT &= ~(SERVO_2); TA0CCR0 = servo1pos - servo2pos; } else { P1OUT &= ~(SERVO_1); TA0CCR0 = servo2pos - servo1pos; } servo_counter++; } else { TA0CCR0 = 20000 - servo1pos; P1OUT &= ~(SERVO_1); P1OUT &= ~(SERVO_2); servo_counter = 0; } } //ADC10 interupt routine #pragma vector = ADC10_VECTOR __interrupt void ADC10_ISR(void) { if (ADC_counter == 0) //X-axis { ADC10CTL0 &= ~ADC10ENC; ADC10MCTL0 = ADC10SREF_0 + ADC10INCH_13; //Next channel is the Y-axis ADCResult_X = ADC10MEM0; ADC_counter++; ADC10CTL0 |= ADC10ENC | ADC10SC; } else if (ADC_counter == 1) //Y-axis { ADC10CTL0 &= ~ADC10ENC; ADC10MCTL0 = ADC10SREF_0 + ADC10INCH_14; //Next channel is the Z-axis ADCResult_Y = ADC10MEM0; ADC_counter++; ADC10CTL0 |= ADC10ENC | ADC10SC; } else //Z-axis { ADC10CTL0 &= ~ADC10ENC; ADC10MCTL0 = ADC10SREF_0 + ADC10INCH_12; //Next channel is the X-axis ADCResult_Z = ADC10MEM0; ADC_counter = 0; ADC10CTL0 |= ADC10ENC | ADC10SC; } }
     
    http://longhornengineer.com/projects/code/msp-exp430-accel-and-servo/
  12. Like
    jsolarski reacted to RobG in 595 Expansion Board   
    Wiring 595s on my proto board every time I wanted to try something became so annoying and frequent that I have decided to create my own expansion board.
    Below is my latest design which will fit on 5x5 board ( 10/$10 Seeed/iTead deal,) has two 74hc595s and two TPIC6C595s. Serial inputs and outputs of all chips can be freely configured via J2, allowing easy ordering of shift registers.
     
    J1 - power and 3 serial inputs: data, clock, latch
    J2 - configuration jumpers: 10-11, 9-8, 7-6, 4-3 for basic 595-595-TPIC-TPIC
     
    Can anyone spot any problems? Any suggestions?
    I wanted to add current limiting resistors to 595's outputs, but decided not to.
     


  13. Like
    jsolarski reacted to DanAndDusty in nokia 5510   
    I have one of these LCDs though on a different board. I wrote a "library" for it.
     
    Put the 2 files in your project directory, Alter the #defines in PCD8544.c to reflect your pins (LCD_SCE etc), in your projects main source file #include "PCD8544.h" in your main() call LCD_init() to setup the lcd, then you can use LCD_gotoXY, LCD_writeString, LCD_writeChar etc.
     
    This was my first "non blinky light" code written for the MSP and I haven't gone back to tidy/refactor but it works. It uses bit banging not the hardware SPI so there are many things that could be tidied up/optimised. Im also including a lil proggie that displays Temp/Vcc and ADC readings for Pin 1.3 and displays the results on the LCD. This code is a quick hack to test the library/get to know some of the ADC so don't take the code in it as anything other than a test framework.
     
    Hope this helps.
     
    Dan
     
    Zipped source files :ADC_and_LCD.zip
     
    P.S. I added the file as a zip file as the board disallows files with a .h extension
  14. Like
    jsolarski reacted to oPossum in MSP430F149 Soldering and Packaging   
    Those are all PM package (64 pin LQFP). The G4, R and RG4 designate how chips are packaged together - such as tape reel or tray.
     
    TI Package Info
  15. Like
    jsolarski reacted to oPossum in Precision 12 MHz clock for Launchpad MCU   
    The MSP430F1612 on the Launchpad provides a 12 MHz clock to the TUSB3410 chip. This clock can also be used by the MSP430 in the 20 pin socket.
     
    Clock on pin 49 of F1612

     
    Mask off pin 49 with Kapton tape and solder a 1k resistor to the pin.
    Connect the other end of the resistor to the lower pad of C21 using a short wire.
     

     
    This test program will flash the red LED five times with the DCO at ~1 MHz and then switch to the 12 MHz external clock.
     

    #include "msp430g2231.h" void main(void) { unsigned i; volatile unsigned n = 0; WDTCTL = WDTPW | WDTHOLD; P1DIR = 0x01; P1SEL = 0x00; i = 10; do { P1OUT ^= 1; while(--n); } while(--i); BCSCTL3 = LFXT1S0 | LFXT1S1; // - Set XT1 clock type as external do { // - Wait for MSP430 to detect clock is stable IFG1 &= ~OFIFG; // Clear OFIFG n = 250; while(--n); // Wait a while } while(IFG1 & OFIFG); // Loop until OFIFG remains cleared BCSCTL2 = SELM1 | SELM0 | SELS; // - Use LFXT1CLK as clock source do { P1OUT ^= 1; while(--n); } while(1); }
  16. Like
    jsolarski reacted to oPossum in 32k interupts a second?   
    Using a 32768 Hz xtal for the phase accumulator clock is a very clever idea. I like it.
     
    Here is some code that seems to work. I just briefly tested it, so there may be some bugs.
     
    Timer A is switched between ACLK at 32768 Hz and SMCLK at ~16 MHz as needed.
     
    This will generate two sine waves with a frequency resolution of 0.5 Hz.
     
    This is the core code...

    // Phase increments are in units of 0.5 Hz static unsigned pi1 = 440 * 2; // Phase increment 1 static unsigned pi2 = 660 * 2; // Phase increment 2 void main(void) { WDTCTL = WDTPW | WDTHOLD; // Disable watchdog BCSCTL1 = XT2OFF | 15; // Set DCO to aprox 16 MHz DCOCTL = 0x86; // P1DIR = 0xF3; // I/O assignment P1REN = 0x00; // P1OUT = 0x02; // P1SEL = 0x50; // Enable Timer A output, SMCLK output TACTL = TASSEL_1 | MC_1 | TAIE; // Timer A config: ACLK, count up, ovrflow int enabled TAR = 0xFF00; // Force interrupt soon TACCR0 = 420; // Setup Timer A period for under 32768 kHz TACCR1 = TACCR0 / 2; // Setup Timer A compare to midpoint TACCTL1 = OUTMOD_7; // Setup Timer A reset/set output mode _EINT(); // Enable interrupts for(;; } #pragma vector = TIMERA0_VECTOR // Timer A Period interrupt __interrupt void timer_a0_isr(void) // This interrupt will occur when the PWM period is complete { // TACCTL0 &= ~CCIE; // Disable period interrupt TACTL = TASSEL_1 | MC_1 | TAIE; // Timer A config: ACLK, count up, overflow interrupt TAR = 0xFFFF; // Interrupt at next clock edge volatile unsigned z = TAIV; // Clear any pending interrupts } // #pragma vector = TIMERA1_VECTOR // Timer A Overflow interrupt __interrupt void timer_a1_isr(void) // This interrupt will occur when the 32 kHz xtal clock // (ACLK) causes Timer A to overflow from 65535 to 0 { // static unsigned pa1 = 0; // Phase accumulator for tone 1 static unsigned pa2 = 0; // Phase accumulator for tone 2 static unsigned sample = 218; // PWM sample // TACCR1 = sample; // Output previous PWM sample TACTL = TASSEL_2 | MC_1 | TACLR; // Timer A config: SMCLK, count up, clear TACCTL0 &= CCIFG; // Clear any pending interrupt TACCTL0 |= CCIE; // Enable period interrupt // // Get pointer to sine table entry signed char const *ps1 = sine + (pa1 >> 8); signed char const *ps2 = sine + (pa2 >> 8); // Interpolate sine table entry and next sine table entry sample = 218 + \ interpolate(ps1[0], ps1[1], pa1 & 0x00FF) + \ interpolate(ps2[0], ps2[1], pa2 & 0x00FF); // pa1 += pi1; // Update phase accumulators pa2 += pi2; // } //
     
    Complete code attached.
    two_tone_32k_xtal.zip
  17. Like
    jsolarski reacted to nobody in MSP430 Frequency Counter   
    One error is in line:
    TA1CTL |= TASSEL_1 + TAIE;
    Your timer not running. Edited line:
    TA1CTL |= TASSEL_1 + TAIE + MC_2; /* Timer A mode control: 2 - Continous up */
    And into interrupt routine maybe try this (you can see all captures, not only the first ...):
    P1OUT ^= BIT0; // Toggle Red LED using exclusive-OR
  18. Like
    jsolarski got a reaction from MarkoeZ in 2 Questions on how to use the MSP430g2252 the best way   
    No problem lol
     
    Just some reading that may help
     
    http://cnx.org/content/m12321/latest/ --This is for interrupts
  19. Like
    jsolarski got a reaction from MarkoeZ in 2 Questions on how to use the MSP430g2252 the best way   
    using the WDT for serial timing would not be very good, WDT has very limited options, I would suggest use one of the C/C registers for your serial timing and use the other 2 for PWM, and if you need more use the WDT interval timer
     
     
     
    so let me exapnd a little -- WDT CLK can only be sourced from 2 places SMCLK and ACLK --
    and the divider options, CLK/ 32768, CLK/ 8192, CLK/512 CLK/ 64
     
    other then these settings you really cant set the speed
  20. Like
    jsolarski reacted to MarkoeZ in 2 Questions on how to use the MSP430g2252 the best way   
    hmm, you mean i could use a main interrupt powered by the single timer, and just check,add to and reset individual integers for motor drive pwm, and toggle pins there?
     
    sounds interesting
     
    Edit: not sure how to time the serial then though... :?
     
    Edit2: ooooh wait, i have 3 ccr's on the timer, i could use one for the serial, and 2 for the motor drive pwm? since this first project will only use pwm on the forward/backward drive, that might be enough, right?
     
    Another edit: example 3 in this pdf looks very useful for that: http://www.ccs.neu.edu/home/noubir/Courses/CSU610/S07/MSP430-Clock-Timers.pdf
  21. Like
    jsolarski reacted to SugarAddict in 32k interupts a second?   
    16000000/32768=488.28125
     
    If you can keep the ISR below that then you should be ok. If you OC your chip you can get upwards of another 100 ticks.
  22. Like
    jsolarski reacted to nuetron in BJT H-Bridge   
    Updated the circuit in my last post, now it looks like this, allows you to go forward, reverse , freewheel, and brake, with two logic inputs.
     
    Y'all may like it, uses half of three ICs. (In other words, you can add on another motor without adding more ICs.)
     
    EDIT: Added two caps on either side of the inductor, so you can see it "Freewheeling".
  23. Like
    jsolarski got a reaction from bluehash in MSP430 Frequency Counter   
    Timer A setup --this is for the 2452/53 the bare minimum settings --no ISR
     
     
    TACTL |= TASSEL_1; //sets Timer A to ACLK
     
    TACCTL0 |= MC_1 + CAP; //sets up Capture/compare register for Capture on rising edge and enable capture
     
    TACCTL1 |= MC_1 + CAP;
     
    TACCTL2 |= MC_1 + CAP;
     
    in TACCTLx register there is a setting to tell it what pin or internal connection to activate the Capture function.
    CCISx 00 CCCIxA
    01 CCIxB
    10 grnd
    11 vcc
     
    This setting allows you to use either an external pin or SW to use the capture function , I would definitely read CH12 in SLA144x.pdf Family user guide, x= version letter
     
    Your approach to the whole thing should work correctly, and you may be able to find some examples from iDave, he has been working on the "TAOS light to frequency IC" but dont know if he has posted any code
  24. Like
    jsolarski reacted to gordon in Where to begin...What to buy   
    Welcome on board!
     
    You will probably be right at home starting off with MSP430, especially if people around you already use it. I have no particular experience with robotics as such, but stick a ~$2 MSP430G2553 (currently the biggest MCU the LaunchPad supports) in the $4.30 LaunchPad, and you already have a pretty beefy setup to start with. At 6 bucks, you can't really go wrong .
     
    Olimex makes some nice starter kits at pretty reasonable prices, if kits are what tickle your fancy. However, the LP is all you need to interface with any MSP that supports being tackled with Spy-Bi-Wire (which is most of those you want, at least for starters), so if all else fails, you can just get an LP for programming, and any beefy MSP430 (where I believe even the bigger ones are under $10 or thereabouts) on a breakout board, and there you fly.
     
    All in all, even in the very unlikely event of you realizing this is not your keg of beer, the whole experiment will have cost you about $20. Whether or not you are willing to risk this is up to you, but I don't think you can go too wrong.
  25. Like
    jsolarski reacted to zborgerd in Where to begin...What to buy   
    I/O might be one of your biggest limitations on the Launchpad (not memory). Same would apply to an Arduino UNO (though probably not the Mega). Thought there are certainly ways around that by interfacing other circuits.
     
    Launchpad is $4.30, and as Gordon suggested - The MSP430G2553 is pretty cheap and will increase your flash to 16 KB. You can probably even get free samples sent from TI. If you find that you need a bit more I/O and still want to keep the price down part-way through the project, then you should be able to easily modify your code for the new FraunchPad:
     
    http://focus.ti.com/docs/toolsw/folders ... r5739.html
     
    They are currently $15 with half-off promo code that is noted on 430h's main page (I haven't heard that it's expired yet).
     
    And if you think that you need even more memory and IO, then you are going to have to start looking at some other options. But you can program any Spy-By-Wire MSP430 with the Launchpad's emulator. You will reach a 16 KB limit with Code Composer Studio v.4 free edition and will need to use MSP430 GCC (as many of us do).
×
×
  • Create New...