Jump to content
43oh

shayoz

Members
  • Content Count

    0
  • Joined

  • Last visited

Reputation Activity

  1. Like
    shayoz reacted to juani_c in Launchpad+Accelerometer+Processing=Snake game!!!   
    I made this little project and wanted to share it. The code is mostly from "Half Duplex Software UART on the LaunchPad" by NJC, I just added the ADC parts I needed. The Processing application send first a "X" and the LP answer with the value from one of the axes, then send a "Y" and you get the value from the other axis. After that the soft update the snake position and repeat the process. In order to start the game you have to click on the START button (pretty obvious), you lose if the snake touchs any of the sides, also the length and speed increase as you eat the little boxes.
    The codes are far from perfect and can be improved. I'm making a little video (that actually took me almost the same amount of time I spent programming) and I'll upload it in a while.
     
     
    EDIT:here is the video
    Launchpad-Snake.rar
  2. Like
    shayoz 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
     
    Simplify
    V = A * 0.0014663
     
    Substitute ADC conversion forumula for voltage in the temperature conversion formula.
    C = A * 0.0014663 / 0.00355 - 277.75
     
    Simplify
    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
     
    Simplify.
    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
     
    Simplify.
    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
     
    Simplifiy
    F = A * 0.7435 - 467.95
     
    Convert to integer
    F = (A * 48724 - 30667156) >> 16
     
    Improve rounding
    F = (A * 48724 - 30667156 + 32768) >> 16
     
    Simplify
    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.
     
    main.c

    #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 } //
     
    lcd.h

    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);
     
    lcd.c

    #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); }
×
×
  • Create New...