Jump to content


  • Content Count

  • Joined

  • Last visited

  • Days Won


Reputation Activity

  1. Like
    sirri got a reaction from simpleavr in light alarm clock project using msp430   
    Here is the photo albume of the progress: i am soldering : ) and making some kind of "shield"
    (i should have plan the positions and paths better though)
  2. Like
    sirri got a reaction from roadrunner84 in size matters! [humor:P]   
  3. Like
    sirri reacted to oPossum in Using the internal temperature sensor   
    TI has some sample code for the internal temperature sensor, but it does not explain how to scale the ADC reading to useful units of degrees. Here is a step-by-step explanation of how to do the scaling with integer math for degrees C, K and F. There is also sample code to display the temperature on a Nokia 5110 LCD.

    The data sheet (SLAU144) has this formula for converting temperature in degrees Celsius to voltage.
    V = 0.00355 * C + 0.986

    What we need is a formula for converting voltage to temperature.
    Rewrite the data sheet fomula with temperature on the left
    0.00355 * C + 0.986 = V
    Divide both sides by 0.00355
    C + 277.75 = V / 0.00355
    Subtract 277.75 from both sides
    C = V / 0.00355 - 277.75
    Now we have a formula for converting voltage to temperature.
    The data sheet has this formula for converting voltage to ADC value, once again the opposite of what we neeed.

    For Vref- == 0
    A = 1023 * V / Vref
    Swap sides
    1023 * V / Vref = A
    Multiply by Vref
    1023 * V = A * Vref
    Divide by 1023
    V = A * Vref / 1023
    For a 1.5V reference
    V = A * 1.5 / 1023
    V = A * 0.0014663
    Substitute ADC conversion forumula for voltage in the temperature conversion formula.
    C = A * 0.0014663 / 0.00355 - 277.75
    C = A * 0.413 - 277.75
    Now we have a formula to convert ADC reading to temperature.
    It uses real numbers, so floating point math is required for good precision.
    Floating point is slow and requires more flash, so let's use integer math instead.
    Multiply by 65536 (2^16) and then divide by the same.
    C = (A * 27069 - 18202393) / 65536
    Use a right shift instead of divide. This will become a move of high word to low word.
    C = (A * 27069 - 18202393) >> 16
    Add 0.5 * 65536 to impove rounding.
    C = (A * 27069 - 18202393 + 32768) >> 16
    C = (A * 27069 - 18169625) >> 16
    So that is how to go from ADC to degrees Celsius.
    To convert degrees C to degees K.
    K = C + 273.15
    Applied to ADC to degrees C conversion formula.
    K = (A * 27069 - 18169625) >> 16 - 273.15
    Implement with integer math by multiplying by 65536
    K = (A * 27069 - 18169625 - 17,901,158) >> 16
    K = (A * 27069 - 268467) >> 16
    To convert degrees C to degrees F.
    F = C * 9 / 5 + 32
    Applied to voltage to degrees C conversion forumula
    F = (V / 0.00355 - 277.75) * 9 / 5 + 32
    Multiply by 9
    F = (V / 0.0003944 - 2499.75) / 5 + 32
    Divide by 5
    F = (V / 0.0019722 - 499.95) + 32
    Add 32
    F = V / 0.0019722 - 467.95
    Substitute ADC to voltage forumula
    F = A * 0.0014663 / 0.0019722 - 467.95
    F = A * 0.7435 - 467.95
    Convert to integer
    F = (A * 48724 - 30667156) >> 16
    Improve rounding
    F = (A * 48724 - 30667156 + 32768) >> 16
    F = (A * 48724 - 30634388) >> 16
    So now we have three formulas to convert ADC reading to degrees C, K and F using fast and compact integer math.
    C = (A * 27069 - 18169625) >> 16
    K = (A * 27069 - 268467) >> 16
    F = (A * 48724 - 30634388) >> 16
    Using the ADC value, rather than a different temperature scale, will ensure greatest precision for each temperature scale.

    #include #include #include "lcd.h" #define ADC_SLEEP // Sleep during ADC conversion //#define SHOW_ADC // Show ADC raw and ADC millivolts // Print integer from -999 to 9999 using 12 x 16 font void print_int(int i, const unsigned y) { if(i < -999 || i > 9999) return; const unsigned neg = i < 0; if(neg) i = -i; div_t d; d.quot = i; unsigned x = 48; do { d = div(d.quot, 10); pd12(d.rem, x -= 12, y); } while(d.quot); if(neg) pd12(14, x -= 12, y); while(x) pd12(10, x -= 12, y); } // Print integer from 0 to 9999 vertically using 6 x 8 font void print_v(int i, unsigned x) { unsigned y = 4; unsigned c; if(i < 0 || i > 9999) return; div_t d; d.quot = i; do { d = div(d.quot, 10); c = d.rem + '0'; lcd_print((char *)&c, x, --y); } while(d.quot); c = ' '; while(y) lcd_print((char *)&c, x, --y); } void main(void) { unsigned adc; // ADC value int c, k, f; // Temperature in degrees C, K, and F unsigned mv; // ADC reading in millivolts // WDTCTL = WDTPW | WDTHOLD; // Disable watchdog reset // lcd_init(); // Initialize LCD lcd_clear(0); // pd12(15, 48, 0); // Degrees pd12(17, 59, 0); // F pd12(15, 48, 2); // Degrees pd12(16, 58, 2); // C pd12(15, 48, 4); // Degrees pd12(18, 59, 4); // K #ifdef SHOW_ADC // lcd_print("Am", 72, 4); // AD / mV lcd_print("DV", 72, 5); // #endif // // ADC10CTL0 = 0; // Configure ADC ADC10CTL1 = INCH_10 | ADC10DIV_3; // ADC10CTL0 = SREF_1 | ADC10SHT_3 | REFON | ADC10ON | ADC10IE; //ADC10CTL0 = SREF_1 | ADC10SHT_3 | REFON | ADC10ON | ADC10IE | REF2_5V; #ifdef ADC_SLEEP // ADC10CTL0 |= ADC10IE; // Enable ADC conversion complete interrupt #endif // // for(; { // for-ever #ifdef ADC_SLEEP // ADC10CTL0 |= (ENC | ADC10SC); // Begin ADC conversion __bis_SR_register(LPM0_bits + GIE); // Sleep until conversion complete #else // ADC10CTL0 &= ~ADC10IFG; // Clear conversion complete flag ADC10CTL0 |= (ENC | ADC10SC); // Begin ADC conversion while(!(ADC10CTL0 & ADC10IFG)); // Wait for conversion to complete #endif // // adc = ADC10MEM; // Read ADC // // Convert to temperature c = ((27069L * adc) - 18169625L) >> 16; // Vref = 1.5V //c = ((45115L * adc) - 18169625L) >> 16; // Vref = 2.5V // k = ((27069L * adc) - 268467L) >> 16; // Vref = 1.5V //k = ((45115L * adc) - 268467L) >> 16; // Vref = 2.5V // f = ((48724L * adc) - 30634388L) >> 16; // Vref = 1.5V //f = ((81206L * adc) - 30634388L) >> 16; // Vref = 2.5V // // Convert to millivolts mv = (96094L * adc + 32768) >> 16; // Vref = 1.5V //mv = (160156L * adc + 32768) >> 16; // Vref = 2.5V // // Display on LCD print_int(f, 0); // Degrees F print_int(c, 2); // Degrees C print_int(k, 4); // Degrees K // #ifdef SHOW_ADC // print_v(adc, 72); // ADC print_v(mv, 78); // ADC millivolts #endif // // //__delay_cycles(100000); // } // } #pragma vector = ADC10_VECTOR // ADC conversion complete interrupt __interrupt void ADC10_ISR(void) // { // __bic_SR_register_on_exit(LPM0_bits); // Wakeup main code } //

    typedef enum { lcd_command = 0, // Array of one or more commands lcd_data = 1, // Array of one or more bytes of data lcd_data_repeat = 2 // One byte of data repeated } lcd_cmd_type; void lcd_send(const unsigned char *cmd, unsigned len, const lcd_cmd_type type); void lcd_home(void); void lcd_pos(unsigned char x, unsigned char y); void lcd_clear(unsigned char x); void lcd_init(void); void lcd_print(char *s, unsigned x, unsigned y); void pd12(unsigned n, unsigned x, unsigned y);

    #include #include "lcd.h" //static const unsigned TXD = BIT1; static const unsigned RXD = BIT2; static const unsigned SWITCH = BIT3; static const unsigned LCD_CLK = BIT5; static const unsigned LCD_BACKLIGHT = BIT6; static const unsigned LCD_DATA = BIT7; static const unsigned LCD_DC = BIT0; // PORT2 static const unsigned LCD_CE = BIT1; // PORT2 void lcd_send(const unsigned char *cmd, unsigned len, const lcd_cmd_type type) { register unsigned mask; P2OUT &= ~LCD_CE; do { mask = 0x0080; do { if(*cmd & mask) { P1OUT &= ~LCD_CLK; P1OUT |= LCD_DATA; } else { P1OUT &= ~(LCD_CLK | LCD_DATA); } P1OUT |= LCD_CLK; mask >>= 1; } while(!(mask & 1)); if(!type) P2OUT &= ~LCD_DC; if(*cmd & mask) { P1OUT &= ~LCD_CLK; P1OUT |= LCD_DATA; } else { P1OUT &= ~(LCD_CLK | LCD_DATA); } P1OUT |= LCD_CLK; P2OUT |= LCD_DC; if(!(type & 2)) ++cmd; } while(--len); P2OUT |= LCD_CE; } static const unsigned char home[] = { 0x40, 0x80 }; void lcd_home(void) { lcd_send(home, sizeof(home), lcd_command); } void lcd_pos(unsigned char x, unsigned char y) { unsigned char c[2]; c[0] = 0x80 | x; c[1] = 0x40 | y; lcd_send(c, sizeof(c), lcd_command); } void lcd_clear(unsigned char x) { lcd_home(); lcd_send(&x, 504, lcd_data_repeat); lcd_home(); } void lcd_init(void) { static const unsigned char init[] = { 0x20 + 0x01, // function set - extended instructions enabled //0x80 + 64, // set vop (contrast) 0 - 127 0x80 + 66, // set vop (contrast) 0 - 127 0x04 + 0x02, // temperature control 0x10 + 0x03, // set bias system 0x20 + 0x00, // function set - chip active, horizontal addressing, basic instructions 0x08 + 0x04 // display control - normal mode }; P1REN = RXD | SWITCH; P1DIR = LCD_CLK | LCD_BACKLIGHT | LCD_DATA; P1OUT = LCD_CLK | RXD | SWITCH | LCD_BACKLIGHT; P2REN = 0; P2DIR = LCD_DC | LCD_CE; P2OUT = LCD_CE; __delay_cycles(20000); P2OUT |= LCD_DC; __delay_cycles(20000); lcd_send(init, sizeof(init), lcd_command); } static const unsigned char font6x8[96][5] = { 0x00, 0x00, 0x00, 0x00, 0x00, // 20 32 0x00, 0x00, 0x5F, 0x00, 0x00, // 21 33 ! 0x00, 0x07, 0x00, 0x07, 0x00, // 22 34 " 0x14, 0x7F, 0x14, 0x7F, 0x14, // 23 35 # 0x24, 0x2A, 0x7F, 0x2A, 0x12, // 24 36 $ 0x23, 0x13, 0x08, 0x64, 0x62, // 25 37 % 0x36, 0x49, 0x56, 0x20, 0x50, // 26 38 & 0x00, 0x08, 0x07, 0x03, 0x00, // 27 39 ' 0x00, 0x1C, 0x22, 0x41, 0x00, // 28 40 ( 0x00, 0x41, 0x22, 0x1C, 0x00, // 29 41 ) 0x2A, 0x1C, 0x7F, 0x1C, 0x2A, // 2A 42 * 0x08, 0x08, 0x3E, 0x08, 0x08, // 2B 43 + 0x00, 0x40, 0x38, 0x18, 0x00, // 2C 44 , 0x08, 0x08, 0x08, 0x08, 0x08, // 2D 45 - 0x00, 0x00, 0x60, 0x60, 0x00, // 2E 46 . 0x20, 0x10, 0x08, 0x04, 0x02, // 2F 47 / 0x3E, 0x51, 0x49, 0x45, 0x3E, // 30 48 0 0x00, 0x42, 0x7F, 0x40, 0x00, // 31 49 1 0x42, 0x61, 0x51, 0x49, 0x46, // 32 50 2 0x21, 0x41, 0x49, 0x4D, 0x33, // 33 51 3 0x18, 0x14, 0x12, 0x7F, 0x10, // 34 52 4 0x27, 0x45, 0x45, 0x45, 0x39, // 35 53 5 0x3C, 0x4A, 0x49, 0x49, 0x30, // 36 54 6 0x41, 0x21, 0x11, 0x09, 0x07, // 37 55 7 0x36, 0x49, 0x49, 0x49, 0x36, // 38 56 8 0x06, 0x49, 0x49, 0x29, 0x1E, // 39 57 9 0x00, 0x00, 0x14, 0x00, 0x00, // 3A 58 : 0x00, 0x00, 0x40, 0x34, 0x00, // 3B 59 ; 0x00, 0x08, 0x14, 0x22, 0x41, // 3C 60 < 0x14, 0x14, 0x14, 0x14, 0x14, // 3D 61 = 0x00, 0x41, 0x22, 0x14, 0x08, // 3E 62 > 0x02, 0x01, 0x51, 0x09, 0x06, // 3F 63 ? 0x3E, 0x41, 0x5D, 0x59, 0x4E, // 40 64 @ 0x7C, 0x12, 0x11, 0x12, 0x7C, // 41 65 A 0x7F, 0x49, 0x49, 0x49, 0x36, // 42 66 B 0x3E, 0x41, 0x41, 0x41, 0x22, // 43 67 C 0x7F, 0x41, 0x41, 0x41, 0x3E, // 44 68 D 0x7F, 0x49, 0x49, 0x49, 0x41, // 45 69 E 0x7F, 0x09, 0x09, 0x09, 0x01, // 46 70 F 0x3E, 0x41, 0x49, 0x49, 0x7A, // 47 71 G 0x7F, 0x08, 0x08, 0x08, 0x7F, // 48 72 H 0x00, 0x41, 0x7F, 0x41, 0x00, // 49 73 I 0x20, 0x40, 0x41, 0x3F, 0x01, // 4A 74 J 0x7F, 0x08, 0x14, 0x22, 0x41, // 4B 75 K 0x7F, 0x40, 0x40, 0x40, 0x40, // 4C 76 L 0x7F, 0x02, 0x1C, 0x02, 0x7F, // 4D 77 M 0x7F, 0x04, 0x08, 0x10, 0x7F, // 4E 78 N 0x3E, 0x41, 0x41, 0x41, 0x3E, // 4F 79 O 0x7F, 0x09, 0x09, 0x09, 0x06, // 50 80 P 0x3E, 0x41, 0x51, 0x21, 0x5E, // 51 81 Q 0x7F, 0x09, 0x19, 0x29, 0x46, // 52 82 R 0x26, 0x49, 0x49, 0x49, 0x32, // 53 83 S 0x01, 0x01, 0x7F, 0x01, 0x01, // 54 84 T 0x3F, 0x40, 0x40, 0x40, 0x3F, // 55 85 U 0x1F, 0x20, 0x40, 0x20, 0x1F, // 56 86 V 0x3F, 0x40, 0x38, 0x40, 0x3F, // 57 87 W 0x63, 0x14, 0x08, 0x14, 0x63, // 58 88 X 0x03, 0x04, 0x78, 0x04, 0x03, // 59 89 Y 0x61, 0x51, 0x49, 0x45, 0x43, // 5A 90 Z 0x00, 0x7F, 0x41, 0x41, 0x41, // 5B 91 [ 0x02, 0x04, 0x08, 0x10, 0x20, // 5C 92 '\' 0x00, 0x41, 0x41, 0x41, 0x7F, // 5D 93 ] 0x04, 0x02, 0x01, 0x02, 0x04, // 5E 94 ^ 0x80, 0x80, 0x80, 0x80, 0x80, // 5F 95 _ 0x00, 0x03, 0x07, 0x08, 0x00, // 60 96 ' 0x20, 0x54, 0x54, 0x54, 0x78, // 61 97 a 0x7F, 0x28, 0x44, 0x44, 0x38, // 62 98 b 0x38, 0x44, 0x44, 0x44, 0x28, // 63 99 c 0x38, 0x44, 0x44, 0x28, 0x7F, // 64 100 d 0x38, 0x54, 0x54, 0x54, 0x18, // 65 101 e 0x00, 0x08, 0x7E, 0x09, 0x02, // 66 102 f 0x18, 0xA4, 0xA4, 0xA4, 0x7C, // 67 103 g 0x7F, 0x08, 0x04, 0x04, 0x78, // 68 104 h 0x00, 0x44, 0x7D, 0x40, 0x00, // 69 105 i 0x00, 0x20, 0x40, 0x40, 0x3D, // 6A 106 j 0x00, 0x7F, 0x10, 0x28, 0x44, // 6B 107 k 0x00, 0x41, 0x7F, 0x40, 0x00, // 6C 108 l 0x7C, 0x04, 0x78, 0x04, 0x78, // 6D 109 m 0x7C, 0x08, 0x04, 0x04, 0x78, // 6E 110 n 0x38, 0x44, 0x44, 0x44, 0x38, // 6F 111 o 0xFC, 0x18, 0x24, 0x24, 0x18, // 70 112 p 0x18, 0x24, 0x24, 0x18, 0xFC, // 71 113 q 0x7C, 0x08, 0x04, 0x04, 0x08, // 72 114 r 0x48, 0x54, 0x54, 0x54, 0x24, // 73 115 s 0x04, 0x04, 0x3F, 0x44, 0x24, // 74 116 t 0x3C, 0x40, 0x40, 0x20, 0x7C, // 75 117 u 0x1C, 0x20, 0x40, 0x20, 0x1C, // 76 118 v 0x3C, 0x40, 0x30, 0x40, 0x3C, // 77 119 w 0x44, 0x28, 0x10, 0x28, 0x44, // 78 120 x 0x4C, 0x90, 0x90, 0x90, 0x7C, // 79 121 y 0x44, 0x64, 0x54, 0x4C, 0x44, // 7A 122 z 0x00, 0x08, 0x36, 0x41, 0x00, // 7B 123 { 0x00, 0x00, 0x77, 0x00, 0x00, // 7C 124 | 0x00, 0x41, 0x36, 0x08, 0x00, // 7D 125 } 0x02, 0x01, 0x02, 0x04, 0x02, // 7E 126 ~ 0x00, 0x06, 0x09, 0x09, 0x06, // 7F 127 degrees }; void lcd_print(char *s, unsigned x, unsigned y) { unsigned char c[2]; c[0] = 0x80 | x; c[1] = 0x40 | y; lcd_send(c, sizeof(c), lcd_command); while(*s) { lcd_send(&font6x8[*s - 32][0], 5, lcd_data); lcd_send(&font6x8[0][0], 1, lcd_data); ++s; } } static const unsigned char num11x16[19][11 * 2] = { 0x00,0xF0,0xFC,0xFE,0x06,0x02,0x06,0xFE,0xFC,0xF0,0x00, // 0 0x00,0x07,0x1F,0x3F,0x30,0x20,0x30,0x3F,0x1F,0x07,0x00, 0x00,0x00,0x08,0x0C,0xFC,0xFE,0xFE,0x00,0x00,0x00,0x00, // 1 0x00,0x20,0x20,0x20,0x3F,0x3F,0x3F,0x20,0x20,0x20,0x00, 0x00,0x0C,0x0E,0x06,0x02,0x02,0x86,0xFE,0x7C,0x38,0x00, // 2 0x00,0x30,0x38,0x3C,0x36,0x33,0x31,0x30,0x30,0x38,0x00, 0x00,0x0C,0x0E,0x86,0x82,0x82,0xC6,0xFE,0x7C,0x38,0x00, // 3 0x00,0x18,0x38,0x30,0x20,0x20,0x31,0x3F,0x1F,0x0E,0x00, 0x00,0x00,0xC0,0x20,0x18,0x04,0xFE,0xFE,0xFE,0x00,0x00, // 4 0x00,0x03,0x02,0x02,0x02,0x22,0x3F,0x3F,0x3F,0x22,0x02, 0x00,0x00,0x7E,0x7E,0x46,0x46,0xC6,0xC6,0x86,0x00,0x00, // 5 0x00,0x18,0x38,0x30,0x20,0x20,0x30,0x3F,0x1F,0x0F,0x00, 0x00,0xC0,0xF0,0xF8,0xFC,0x4C,0xC6,0xC2,0x82,0x00,0x00, // 6 0x00,0x0F,0x1F,0x3F,0x30,0x20,0x30,0x3F,0x1F,0x0F,0x00, 0x00,0x06,0x06,0x06,0x06,0x06,0xC6,0xF6,0x3E,0x0E,0x00, // 7 0x00,0x00,0x00,0x30,0x3C,0x0F,0x03,0x00,0x00,0x00,0x00, 0x00,0x38,0x7C,0xFE,0xC6,0x82,0xC6,0xFE,0x7C,0x38,0x00, // 8 0x00,0x0E,0x1F,0x3F,0x31,0x20,0x31,0x3F,0x1F,0x0E,0x00, 0x00,0x78,0xFC,0xFE,0x86,0x02,0x86,0xFE,0xFC,0xF8,0x00, // 9 0x00,0x00,0x00,0x21,0x21,0x31,0x1D,0x1F,0x0F,0x03,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x70,0x70,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // : 0x00,0x0E,0x0E,0x0E,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, // . 0x00,0x38,0x38,0x38,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x00,0x00,0x00,0xC0,0x30,0x0C,0x00,0x00,0x00,0x00, // / 0x00,0x30,0x0C,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80, // - 0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01, 0x00,0x18,0x3C,0x66,0x66,0x3C,0x18,0x00,0x00,0x00,0x00, // 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0xF0,0xF8,0x0C,0x06,0x02,0x02,0x02,0x02,0x0E,0x0C,0x00, // C 0x03,0x07,0x0C,0x18,0x10,0x10,0x10,0x10,0x1C,0x0C,0x00, 0xFE,0xFE,0x42,0x42,0x42,0x42,0x42,0x42,0x00,0x00,0x00, // F 0x1F,0x1F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, 0xFE,0xFE,0x40,0xE0,0xB0,0x18,0x0C,0x06,0x02,0x00,0x00, // K 0x1F,0x1F,0x00,0x00,0x01,0x03,0x06,0x0C,0x18,0x10,0x00 }; void pd12(unsigned n, unsigned x, unsigned y) { unsigned char c[2]; c[0] = 0x80 | x; c[1] = 0x40 + y; lcd_send(c, 2, lcd_command); lcd_send(num11x16[n], 11, lcd_data); c[1] = 0x41 + y; lcd_send(c, 2, lcd_command); lcd_send(num11x16[n] + 11, 11, lcd_data); }
  4. Like
    sirri got a reaction from bluehash in light alarm clock project using msp430   
    After many hours of working on displays,buttons, menu systems and so on, here is my result work.
    (The clock somehow lags significantly up to 5 minutes in about 6 hours) But i haven't try the new RTC library yet. Maybe that fixes this issue. I have to fix that and also i will make the PCB and external voltage supply for the launchpad etc. The system works as i want for now. I can set the clock (standalone), set the alarm time, set the light modes (i made three modes: light fades in 10 minutes earlier gradually, 20 minutes and 30 minutes earlier)
    buzzer works if you set it at just at the alarm time.. i made some modes but i wish i could use some melodies (but i am too tired of working at the same project for a long time now : ))
    it also shows current temperature and if it is out of your desires min and max. it says it is COLD or HOT on the main loop. You can set the min and max temperature values in the settings menu. It shows the alarm time as well on the main loop, if alarm is set ON.
    I have used three buttons for this project. up/down buttons and a set button. 
    One last note is that finished work will have three 1W power leds.
    Here is the video of my work,
    Critics are welcomed 

    edit: the setup photo is added

  5. Like
    sirri reacted to roadrunner84 in STM32F4DISCOVERY Support?   
    No, Energia can only build for msp430. The Arduino environment is identical, but builds for avr. As the core is gcc, it would be possible to make another one for stm32. Alternatively you can use arm-gcc and Eclipse.
  6. Like
    sirri reacted to Rickta59 in STM32F4DISCOVERY Support?   
    The not-yet-released beta version of Arduino version 1.5 has better support for non-avr chips and a more flexible scheme for invoking arbitrary toolchains. Look at the how it deals with the ARM chip in programmer.txt
    ... # SAM3 compile variables # --------------------- name=Arduino ARM (32-bits) Boards compiler.path={runtime.ide.path}/hardware/tools/g++_arm_none_eabi/bin/ compiler.c.cmd=arm-none-eabi-gcc compiler.c.flags=-c -g -Os -w -ffunction-sections -fdata-sections -nostdlib --param max-inline-insns-single=500 -Dprintf=iprintf compiler.c.elf.cmd=arm-none-eabi-g++ compiler.c.elf.flags=-Os -Wl,--gc-sections compiler.S.flags=-c -g -assembler-with-cpp compiler.cpp.cmd=arm-none-eabi-g++ compiler.cpp.flags=-c -g -Os -w -ffunction-sections -fdata-sections -nostdlib --param max-inline-insns-single=500 -fno-rtti -fno-exceptions -Dprintf=iprintf compiler.ar.cmd=arm-none-eabi-ar compiler.ar.flags=rcs compiler.objcopy.cmd=arm-none-eabi-objcopy compiler.objcopy.eep.flags=-O ihex -j .eeprom --set-section-flags=.eeprom=alloc,load --no-change-warnings --change-section-lma .eeprom=0 compiler.elf2hex.flags=-O binary compiler.elf2hex.cmd=arm-none-eabi-objcopy compiler.ldflags= compiler.size.cmd=arm-none-eabi-size compiler.define=-DARDUINO= # this can be overriden in boards.txt build.extra_flags= ... However, you would still have to supply an implementation of the library code. Not sure how useful the ATMEL SAM chip stuff would be. There is an older version of an STM32 Arduino implementation called Maple from Leaflabs. It is significant effort to support an Arduino style API for arbitrary chips. 
    The new tree for arduino 1.5 is here:
    Personally I would just learn to use the ARM Eclipse plugin.
  7. Like
    sirri reacted to grahamf72 in Real-Time Clock (RTC) Library for the MSP430/LaunchPad   
    That sounds like a good idea in theory, but in practice it proves a bit tricky.  To do software PWM, you need to be able to clock at your oscillation speed x resolution. So to do the equivalent of the current PWM module which runs at approx 500Hz, with a 256 level resolution, you need the interrupt to call at 128kHz. Likewise with Tone, if you want to be able to produce tones that are close to the musical pitches up to the F at the top of the treble clef, you need resolution of at least 10uS to get pitches which will sound close. This equates to a 100kHz clock. So if we are clocking at 128kHz, with a 16MHz main clock that only gives 125 clock cycles for the interrupt to do it's work. Not impossible but it won't leave much in the way of CPU resources for the main program.  By dropping the pulse frequency or the resolution we can get away with a slower interrupt, but we will also lose accuracy of the tones. 
    The way PWM is actually implemented is through the use of the hardware timer/counters. This is done in a separate section of the hardware and doesn't require CPU resources. The actual method is slightly more complex than this example, but for simplicity sake lets say the counter counts from 1 to 256.  If you set an analog level of 100, the pin will be high while the counter counts 1 to 100, it then changes to low while it counts 101 to 256. The clock then restarts at 1 with the pin back to high.  This can all be done in the hardware without the CPU using any clock cycles. 
    Tone is done partly in software, part in hardware. The timer is configured to trip an interrupt at the frequency of the selected tone. Software then toggles the pin. This allows it to be used with any pin, whereas the method for AnalogWrite only works with pins that are connected to the hardware timers.
    The trouble with using the hardware timers is that there aren't many timers available, and only selected pins can be used with each one.  A software option would be far more flexible, but the 430 just doesn't have the grunt to be able to do it effectively. 
    Of course the other issue if you are trying to share the RTC with other functions, is that to get accurate timing for an RTC, the clock source must be the 32.768kHz crystal. However this is just too slow to be able to do PWM or Tone. So apart from the fact that trying to use the one timer for multiple functions causes problems, the crystal clock is too slow to be able to do PWM or tone.
    BTW, my new version of the RTC that uses the Watchdog Timer instead of TimerA is code complete. I am just working on the documentation before I post it.
  8. Like
    sirri got a reaction from pine in size matters! [humor:P]   
  9. Like
    sirri reacted to grahamf72 in Real-Time Clock (RTC) Library for the MSP430/LaunchPad   
    Basically the issue is, the RTC, AnalogWrite & Tone all want use of a Timer. The MSP430G2553 has 2 timers, the MSP430G2452 only has 1 timer. So we have 3 libraries attempting to use 1 or 2 timers, and problems will occur if we attempt to use 1 timer for 2 functions.
    The existing RTC library uses Timer1 if it is available (eg 2553) or Timer0 if not (eg 2452).
    Tone() uses Timer0
    AnalogWrite() uses Timer0 for the pins on port 1, and Timer1 for the pins on port 2 (2553 only, you can't use AnalogWrite to port 2 with the 2452).
    This means you simply cannot use all 3 functions. On the 2553 you can use any 2 with care, on the 2452 you can only use 1.  So with the 2553 you can use RTC + Tone or RTC + AnalogWrite to port 1 or Tone + AnalogWrite to port 2. 
    The soon-to-be-released WDT version of the RTC library doesn't use one of the general purpose Timers so you can take the RTC out of the equation, and use any combination of Tone & AnalogWrite that your chip allows, ie:
    2553 - Tone + AnalogWrite on Port 2 or AnalogWrite on Port 1 & 2
    2452 - Tone or AnalogWrite
    Hope this helps make things a bit clearer.
  10. Like
    sirri reacted to grahamf72 in Real-Time Clock (RTC) Library for the MSP430/LaunchPad   
    Hi Sirri,
    I have good news and bad news I'm afraid.
    The good news is that I am about 99% done with modifying the RTC library to use the WDT. I just want to do a bit more testing before I release it. Also in the good news category is that when the RTC library is using the WDT I can use analogwrite or tone without issue.
    The bad news is that analogwrite and tone don't play well together. I have knocked up a basic sketch that uses analogwrite to vary the brightness of an RGB led based on the time, and to sound a 2 second tone every 30 seconds.  If I don't use analogwrite, the tone plays properly every time. If I do use analogwrite, the 1st tone plays correctly but only for about half the time it should, and 2nd and subsequent tones are broken & jerky.
    Since your project makes use of analogwrite and tone, I think the easiest option is to use a 555 to do your tone and just turn it on/off. Other options would be to use something like a TLC5940 to drive your leds or maybe even a complete re-write of analogwrite & tone.
    EDIT: After a bit more playing and a bit more studying of the Energia code, it looks like Tone & AnalogWrite will play nice together so long as the pins you choose for AnalogWrite are connected to Timer1 - ie P2.1, P2.2, P2.4, P2.5,
  11. Like
    sirri reacted to legailutin in Launchpad in Fritzing?   
    Actually, there is a Launchpad part for fritzing and I already used it once
    Search Launchpad on this page and import the library to Fritzing.
    Hope this helps.
  12. Like
    sirri got a reaction from roadrunner84 in light alarm clock project using msp430   
    Until Grahamf72 updated the useful RTC_plus library, i have played around with 555 timers as an external buzzer controlled by msp430 launchpad
    I am sharing the basic diagram and also the video. I guess the alarm sound is much more powerful than before (in cost of extra circuitry : / )

    Video Link:
  13. Like
    sirri reacted to grahamf72 in Real-Time Clock (RTC) Library for the MSP430/LaunchPad   
    Hi Sirri,
    I think I have a solution by driving the RTC library off the WDT instead of Timer1. I'll post an update to the library in the next few days that will hopefully fix the interference with Tone() & AnalogWrite().
    The drawback is that millis() and delay() will only have 2mS resolution, but I don't foresee that being a major problem.
  14. Like
    sirri reacted to calinp in Real-Time Clock (RTC) Library for the MSP430/LaunchPad   
    Hi Sirri,
    Check this Energia library to see how you can get timer interrupts without disturbing PWM (and tone) generation: http://forum.43oh.com/topic/2861-energia-library-mstimer2/
    Or try using a different pin. According to pins_energia.h "On the 20pin devices, upto 3 analog outputs are available
    T0A1, T1A1 and T1A2 "  
        T1A0, /* 8 - P2.0 note: A0 output cannot be used with analogWrite */     T1A1, /* 9 - P2.1 */     T1A1, /* 10 - P2.2 */     T1A0, /* 11 - P2.3 note: A0 output cannot be used with analogWrite */     T1A2, /* 12 - P2.4 */     T1A2, /* 13 - P2.5 */   Regards, Calin
  15. Like
    sirri got a reaction from vicvelcro in Best information for those new to the MSP430?   
    For Energia compiler users, this link is very important, key to most features:  https://github.com/energia/Energia/wiki/Hardware
  16. Like
    sirri reacted to grahamf72 in Real-Time Clock (RTC) Library for the MSP430/LaunchPad   
    Hi Sirri,
    Unfortunately it probably is the RTC library that is causing the interference with Tone. The Tone & AnalogWrite functions rely on the MSP430's timer, as does the RTC library. Consequently the functions don't play well with the RTC library. There are a couple of solutions. You could use an external oscillator for the buzzer, eg a 555 timer. The output pin could then drive the reset pin of the 555 to turn it on/off.
    To do it in software, you could make some changes to Energia's wiring.c to configure the Watchdog Timer to use the crystal instead of SMCLK and use the WDT interrupt to drive the RTC. I am working on making this an option with the RTC library, but trying to work out the best way of doing it so as to make minimal changes to the actual Energia code. 
    Best of luck.
  17. Like
    sirri reacted to roadrunner84 in Binary watch with MSP430   
    Finally I'll share some of my binary watch project with you guys.

    Some features:
    - 11 LEDs charlieplexed on 2x 3 I/O pins (6 LEDs per 3 I/O lines, one LED not placed)
    - As low power as can get (900 nA in stand-by)
    - 14-pin value lin MSP430
    - watch crystal sourced (32768Hz)
    - two buttons (of which one is on the reset line)
    - well under 2kB code (1.6kB)
    The "display refresh rate" is 512Hz, which makes the "pixel refresh rate" at 85Hz, a comfortable rate for the eye.
    The WDT is used as a minute timer (2 second hardware, 30 iterations in software), sourced from the crystal, I go down to LPM3 then and can run at 900 nanoAmps.
    During display I run in LPM1 from which I wake 512 times per second to update the LED display.
    The reset line is reused as an input line for one of my two buttons, using the NMI I can use it as a reliable button input pin using some nifty software tricks.
    I use the reset line as button input because I ran out of I/O (10 available: 6 for the display, 1 for a button, 2 for the crystal and 1 for a future buzzer)
    I'm busy desiging a PCB for this too (not a booster, a feature complete board). Using a coincell/buttoncell battery I can fit all my components (except the battery and buzzer) on a 11x39mm PCB, targeting for 20x20mm now.
  18. Like
    sirri reacted to cde in light alarm clock project using msp430   
    tone() and notone() are standard Arduino functions. They are part of Energia. They can be seen in the Energia's library folder
  19. Like
    sirri reacted to Druzyek in light alarm clock project using msp430   
    I would check all the physical connections too. I had a strange case where a shift register was hooked up to some LEDs. It worked the first time but instead of resetting after power was completely removed, it would show the last thing it had displayed when the power was reconnected. I couldn't get the MSP430 to communicate with it again until I removed both chips and put them back in. It turned out that one of the wires to ground had come loose.
  20. Like
    sirri reacted to roadrunner84 in light alarm clock project using msp430   
    I doubdt that a control line just enabling the buzzer would get interrupted. You can give it a try and see whether it's working.
  21. Like
    sirri reacted to cde in light alarm clock project using msp430   
    There are some cheap mp3 modules that can be triggered via a simple serial (not uart) protocol or gpio. It would let you play music as an alarm, or sound effects, even in a programmed sequence or in order.
  22. Like
    sirri reacted to grahamf72 in Real-Time Clock (RTC) Library for the MSP430/LaunchPad   
    I have posted an updated version of this library in the "Libraries" section of this forum.  This is quite a significant upgrade. The main changes are:

    Now works with both the MSP430G2553 and the MSP430G2452 processors (with some limitations on the 2452). The library may work on other processors, but I don't have any to test with. Rewrite of the logic used to detect the number of days in a month and leap year detection so that it uses considerably less RAM. Option to use the built-in VLO clock. The VLO is much less accurate than the crystal - about the best that can be achieved is accuracy to within a few minutes per day. The advantage of the VLO is that it frees up 2 IO pins, and can be used if you can't solder the tiny crystal to the launchpad. If you don't need a very accurate clock, or have a means of external synchronisation, the VLO may be sufficient for your needs. The #define's that configure the settings of the timer have been moved to a separate RTCconfig.h file, so they are easier to edit without having to edit the main header file. Documentation has been moved from the header file into a separate .txt file. Some example files have been included in the library.
  23. Like
    sirri reacted to roadrunner84 in light alarm clock project using msp430   
    coincells cannot deliver a lot of current at once. I still edvice disconnecting the VCC jumper when powering externally. I'm not sure what the power circuit of the programmer does when it gets power from the other side.
  24. Like
    sirri reacted to roadrunner84 in light alarm clock project using msp430   
    It sounds to me like your buzzer is intermittent in the first alarm, then in the second those intermissions are closer tohether. The buzzer "hasn't got the time" to start really making noise. Could it be like this?
  25. Like
    sirri reacted to roadrunner84 in light alarm clock project using msp430   
    Awesome, so the programmer part of the launchpad was draining your batteries?
    Ddi you make any progress on your buzzer problem?
  • Create New...