This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

MSP430FG4618 and RS232 at 115200 baud rate

Other Parts Discussed in Thread: MSP430FG4618

I’m trying to transmit data from MSP430FG4618 to a PC via RS232. The baud rate setting is 115200bps with 8 data bits and 1 stop bit (no parity bit and no flow control). In the other words, if I’m correct, each character (byte) I send from MSP430 to PC is 9 bits. Therefore, at 115200bps, I can send a maximum of 115200/9=12800 characters/sec. As shown in my following code, I’m sending 128000 characters and it takes 11 seconds to complete. It takes 110 seconds to send 1280000 characters. In the other words, it’s about 10% slower. I think there might be one of the following possibilities:

1. The internal clock is not precise enough.

2. My code is not efficient enough.

3. It takes 10 bauds to transmit a character (8bits).

Or there's something else.

Can anyone answer my question? Thanks.//Sending 128000 characters to PC at baud rate of 115200bps.  It should take about 10 seconds to send
//each character has 9 bits (8 data bits + 1 stop bit)

 

#include  "msp430xG46x.h"
#include <stdio.h>
#include <string.h>
void USCIA0_UART_P2_Init();
void USCIA0_UART_Transmit(unsigned char c);
void SendString(char* str);
void delay(unsigned int);  //delay in ms
void main(void)
{
    unsigned long i;
    WDTCTL = WDTPW + WDTHOLD;               //Stop WDT
    FLL_CTL0 = (DCOPLUS | XCAP18PF);       //Enable Frequency Multiplier (DCO+) and XIN/XOUT caps to 18pF
    SCFI0 = (FLLD_2 | FN_8);               //Set Multiplier to 2, and DCO range to 8MHz nominal
    SCFQCTL = 121;                         //7.995392Mhz (D=2, N=121, fACLk=32768) f=D*(N+1)*fACLK
    USCIA0_UART_P2_Init();                 //Configure USCI for UART Mode and Use P2.4&P2.5 which are connected to the DB 9 connector
    P1DIR &= ~BIT0|~BIT1;                   //set 2 push buttons to be input
    while ((P1IN&BIT0)) {}                  //    Push button 1 to start sending characters
    for (i=1280000; i>=1; i--)               //send 128000 characters - should take about 10 seconds to transmit
       SendString("x");                     //send a single character x
}

//---------------------------------------------------------------------------------------------------------------
void USCIA0_UART_P2_Init()
{
   UCA0CTL1 |= UCSWRST;      //Configure the USCI with the reset bit held high
   P4SEL &= ~0x0C0;          //P4.7,6 != USCI_A0 RXD/TXD
   P2SEL |= 0x30;            //Set the USCI to use P2.4 and P2.5 for RX/TX
   UCA0CTL1 |= UCSSEL_2;     //Use SMCLK
   UCA0BR0 = 0x45;           //Set Bit Rate to 115200bps with a 8Mhz clock
   UCA0BR1 = 0x00;
   UCA0MCTL = 0x4A;          //Modulation
   UCA0CTL1 &= ~UCSWRST;     //Done configuring so take USCI out of reset
   IE2 |= UCA0RXIE;          //Enable USCI_A0 RX interrupt
return;
}

//---------------------------------------------------------------------------------------------------------------
/*
* The following function sends byte over RS-232 using the USCI A0 in UART mode
*/
void SendString(char* str)
{
     while(!(IFG2 & UCA0TXIFG));   //Wait until transmit buffer is empty
     UCA0TXBUF=str[0];
//return;
}

  • Shang Wu said:
    It takes 10 bauds to transmit a character (8bits)

    Correct. The reason is that it is an asynchroneous connection. So to allow any combination of the 8 data bits, there mus tbe a way to detect the beginning of the first bit. This is done by having a start bit (which is low) and a stop bit (which is high). So after sendign th elast bit, the stop bit will pull the line high and then release it to idle state (which is also high) and the start of the next databyte will be detected by the high/low transition to the low startbit. This way the idle time can be from 0 to whatever. (or you can interpret the stop bit as a minimum idle time between two databytes and their start bit - the fact that you sometimes can define 1.5 or 2 stop bits strenghtens this interpretation).

    Anyway, sending 128000 characters with 115200 Bd will take 11.11s

    hey, as a side effect, it makes calculations of throughput against baudrate much easier - just drop the last zero of the baudrate :)

  • Thanks for then answer and that's exactly what I'm getting.

  • I have a numerical data that is to be sent to PC via RS232 at 115200 bps.  In order to do that, I need to convert the numerical data into ASCII text before transmission.  However, the conversion is very slow in MSP430 with sprintf command.  As shown in the following, if I remove the first line, it sends as fast as I expected.  Once the first line is there, it slows the transmission at least 10x slower.   Any better way of transmitting numerical data via RS232?  (by the way, the numerical data is continuous on the fly - From an ADC.  Therefore, I can't store it into buffer before transmitting.)

     

    Thanks

     

    sprintf(string_data,"%d",num_data);   //decimal integer up to 4 digits 

    SendString(string_data);                

     

  • There are two different ways to convert integers. The fastest and easiest would be to send hexadecimal numbers. It allows masking of 4 bit groups and avoids slow divisions.

    If you want normal decimal, you can use the BCD assembly commands like DADC to convert the number (in the range of 0..9999) to a binary coded decimal (one decimal digit per 4 bits) and then do a simplified hexadecimal conversion (the 'A..F' value won't happen) of the 4*4 bits.
    It is MUCH faster than sprintf, but it requires usage of assembly language.

    Doing it in plain C is also possible, but much slower as it requires a division or a loop of subtractions. Still faster than sprintf:

    example:

    void convert (unsigned int value, unsigned char * dest){
      unsigned char digit = 0;
      unsigned char flag = 0;
      while (value => 1000){
        digit++;
        value -=1000;
      }
      if(digit || flag){
        *dest = digit+48;
        dest++;
        flag=1;
      }
    while (value => 100){
        digit++;
        value -=100;
      }
      if(digit || flag){
        *dest = digit+48;
        dest++;
        flag=1;
      }
    while (value => 10){
        digit++;
        value -=10;
      }
      if(digit || flag){
        *dest = digit+48;
       dest++;
        flag=1;
      }
      *dest= value+48;
      *dest++;
      *dest=0;
      return
    }

    It's not much optimized, but should produce the desired result without leading zeroes (if you want them, remove the IF cases, or add an else case if you want leading spaces instead). Best of all, it just uses subtractions but no divisions which are slooooooow on the MSP.

  • IAR wouldn't compile the code, but I get the idea.  I wish there's an easier solution.

    Thanks.

     

    IAR likes this better

    void convert (unsigned int value, unsigned char * dest){
      unsigned char digit = 0;
      unsigned char flag = 0;
      while (value >= 1000){
        digit++;
        value -=1000;
      }
      if(digit || flag){
        *dest = digit+48;
        dest++;
        flag=1;
      }
    while (value >= 100){
        digit++;
        value -=100;
      }
      if(digit || flag){
        *dest = digit+48;
        dest++;
        flag=1;
      }
    while (value >= 10){
        digit++;
        value -=10;
      }
      if(digit || flag){
        *dest = digit+48;
       dest++;
        flag=1;
      }
      *dest= value+48;
      *dest++;
      *dest=0;
      return;
    }

     

     

    However, I still have problem calling the function (as I haven't programmed C for years).

    I tried calling the function by

     

    char mystring[ ];

    uint16_t ADC_data;

    convert (ADC_data, mystring);

     

    and

     

    char *mystring;

    uint16_t ADC_data;

    convert(ADC_data, *mystring);

    both failed.

  • Actually, the easiest and fastest way to send data over UART is to send them as is without any conversion. Assuming the UART format is 115200,8N1, you can send 8-bit worth of data in 10/115200 seconds. That is 80% efficient. If you convert that data into hex digits, you can only send 4-bit worth of data in the same amount of time and is only 40% efficient. If you convert to decimal digits, aside from the time you spent for conversion, you can only send ~3.3 bits worth of information and is only ~33% efficient. The PC has Meg bytes of memory and GHz CPU, why not let the PC to do the conversion?

  • I thought about doing that, but don't know how to send the data to PC without converting the numerical value to ASCII characters.  Would you please give me a hint on this?  See my previous code.

    Thank you.

  • If "your_data_8" is 8-bit wide (that is, if it is of type "char", "unsigned char", "signed char", "u8", "s8", or whatever you call it) you can simply do a TXBUF=your_data_8 whenever TX is ready for data.

    If "your_data_16" is 16-bit wide, you need to send it in 2 installments. Do a TXBUF=(char)(your_data_16 & 0xFF); first, and a TXBUF=(char)(your_data_16 >> 8); the next time in two consecutive opportunities to do so.

     

  • My data is actually a 16-bit integer that can be divided into lower and higher bytes.

    I don't have the board with me now, but here's what I have.  I will post the result tomorrow. 

    I imagine that the received file would be a bunch of spaghetti characters before interpretation.

    Thanks.

     

     

    main()

    {

    ...

    unsigned char upper_byte;

    unsigned char lower_byte;

    ...

    SendData(upper_byte);

    SendData(lower_byte);

    ...

    }

     

    void SendData(unsigned char c)
    {
            while(!(IFG2 & UCA0TXIFG));   //Wait until transmit buffer is empty
            UCA0TXBUF = c;                 //Send character
    }

     

  • It is very fast now.  Perhaps too fast?  It works only if I put some kind of delay before transmitting to PC.  The PC indeed receives the spaghetti characters as expected.

    Complete code attached, line#76 is where the delay added.

     

    //  This program is for MSP430FG4618 Experimenter's board
    //  COM port setting: Baud rate 115200, Data bit 8, Parity None, Stop bit 1, Flow Control None
    //  Transmitt the value captured by ADC12_CH7
    //  Push Button #1 (S1) - To start capturing the data
    //  Push Button #2 (S2) - End of transmision

    #include <io430xG46x.h>                // Specific device
    #include <intrinsics.h>                // Intrinsic functions
    #include <stdint.h>                    // Integers of defined sizes
    #include <in430.h>
    #include <stdio.h>
    #include <string.h>
    #include "LCDutils2.h"                // TI exp board utility functions
    #define nSS        P3OUT_bit.P3OUT_0    // Output pin for _SS (active low)
    #define LED1  BIT2
    #define LED2  BIT1
    #define datalength 100                         // number of data points to be captured
    uint8_t RXdata1=0, TXdata1 = 0x38;        // Received and transmitted data,
    uint8_t RXdata2=0, TXdata2 = 0x00;        // Received and transmitted data,

    void USCIA0_UART_P2_Init();
    void USCIA0_UART_Transmit(unsigned char c);
    void SendString(char* str);
    void delay(unsigned int);  //delay in ms
    void init_ADC(void);
    void DisplayPush (void);
    void main(void)
    {
      uint16_t ADC_data;
      volatile long i;
            PortsInit();                    // Initialize ports
        LCDInit();   
         WDTCTL = WDTPW + WDTHOLD;               //Stop WDT
        FLL_CTL0 = (DCOPLUS | XCAP18PF);       //Enable Frequency Multiplier (DCO+) and XIN/XOUT caps to 18pF
        SCFI0 = (FLLD_2 | FN_8);               //Set Multiplier to 2, and DCO range to 8MHz nominal
        SCFQCTL = 121;                         //7.995392Mhz (D=2, N=121, fACLk=32768) f=D*(N+1)*fACLK
        USCIA0_UART_P2_Init();                 //Configure USCI for UART Mode and Use P2.4&P2.5 which are connected to the DB 9 connector  
        P5DIR |= 0x02;                         //Set P5.1 to output direction -- LED is connected to this pin
        P3OUT_bit.P3OUT_0 = 1;            // High for nSS inactive
        P3DIR_bit.P3DIR_0 = 1;            // Enable for nSS output
        P3SEL = BIT1 | BIT2 | BIT3;        // Route pins to USCI_B for SPI
        P1DIR &= ~BIT0|~BIT1;                   //set 2 push buttons to be input
       
            UCB0CTL0 = UCCKPL | UCMSB | UCMST | UCMODE_0 | UCSYNC;
        UCB0CTL1 = UCSSEL1 | UCSWRST;    // Clock from SMCLK; hold in reset
        UCB0BR1 = 0;                    // Upper byte of divider word
            UCB0BR0 = 33;   
            UCB0CTL1 &= ~UCSWRST;            // Release from reset
     
    DisplayPush();       
    while (P1IN&BIT0)   //if button is not pushed, stall
    {
    }
    delay(1000);        //delay to debounce
      for (i=1;i<=datalength;i++)
      {
         if ((P1IN&BIT1)==0)                  //quit if button 2 pushed
         {
           P5OUT &= BIT2;
     //      SendString("\n\rEnd of Data \n\r");
           break;
         } 
            P5OUT ^= 0x02;                        // Toggle LED
               nSS = 0;                            // Lower nSS (make active)
               UCB0TXBUF = TXdata1;            // Tx first byte
               while (!(IFG2 & UCB0RXIFG));//wait for the data to be loaded on receiving buffer
               RXdata1 = UCB0RXBUF;            // Store received data (first byte)
               UCB0TXBUF=TXdata2;                      //Tx 2nd byte
               while((UCB0STAT&BIT0));                  //wait for the transmission to complete
               RXdata2 = UCB0RXBUF;            // Store received data (second byte)
               nSS = 1;                            //Raise sync (nSS)
               ADC_data=(RXdata1<<8)+RXdata2;          //Combine High and Low bytes
               DisplayInt(ADC_data);                   //Display data on LCD (decimal)
             
       //TX to PC
               delay(1);
               while(!(IFG2 & UCA0TXIFG));   //Wait until transmit buffer is empty
                  UCA0TXBUF = RXdata1;        //TX first byte
               while(!(IFG2 & UCA0TXIFG));   //Wait until transmit buffer is empty
                  UCA0TXBUF = RXdata2;         //TX 2nd byte
        }     
    }

    //---------------------------------------------------------------------------------------------------------------
    void delay(unsigned int ms)
    {
      unsigned int i, j;
      for (i = 0; i <= ms; i++)
      {
      for (j = 0; j<=999; j++);
      }
    }
    //---------------------------------------------------------------------------------------------------------------
    void USCIA0_UART_P2_Init()
    {
       UCA0CTL1 |= UCSWRST;      //Configure the USCI with the reset bit held high
       P4SEL &= ~0x0C0;          //P4.7,6 != USCI_A0 RXD/TXD
       P2SEL |= 0x30;            //Set the USCI to use P2.4 and P2.5 for RX/TX
       UCA0CTL1 |= UCSSEL_2;     //Use SMCLK
       UCA0BR0 = 0x45;           //Set Bit Rate to 115200bps with a 8Mhz clock
       UCA0BR1 = 0x00;
       UCA0MCTL = 0x4A;          //Modulation
       UCA0CTL1 &= ~UCSWRST;     //Done configuring so take USCI out of reset
       IE2 |= UCA0RXIE;          //Enable USCI_A0 RX interrupt
    return;
    }

  • Shang Wu said:
    IAR wouldn't compile the code

    My fault. Of course it is >= and not =>. Sometimes my right hand types faster than the left. I wrote this function for you and didn't copy it from a working code.

    Anyway, there's still a bug: The 4th line from beelow must be dest++; and not *dest++;

    Second parameter to the function is a pointer to the destination (as used in sprintf as the first). So you need to pass a pointer.

    If you define char * mystring, then mystring is a pointer to char(s). *mystring is the value of the location mystring points to, a char value. To have it work, mystring needs to poitn to a reserved memory location, such as one located with malloc(). So if you need 5 bytes for the buffer, you'll have to use

    char*mystring = (char*)malloc(5);

    Alternatively, you can define an array, but then it must be initialized (not its content, but its destination). The
    char mystring[];
    you used does not allocate memory for the array. You need to define how large this array has to be. It is only allowed to use this kind of 'undefine dsize array' in an extern declaration, trusting that the 'real' array is properly defined in a different code file.

    mspgcc compiler will assume a size of one if this declaration is used on global scope and refuses tho compiler if used locally. With the 'extern' keyword on global scope., mspgcc accepts it but then it needs to be defined elsewhere or the linker will complain.

    If using [] to define an array, the name of the array may be used as pointer too, but it is not a pointer variable (no memory location that holds the address of the data) but rather a label whose value is known to the compiler and directly used as immediate value.

    It is one of the most confusing parts of C for those not used to it.

  • Shang Wu said:
    void delay(unsigned int ms)

    It's nice that you use a delay function, but not so nice how you implemented it.

    FOR loops are not suitable for delays. Depending on th eproject settings and the compiler used, this kidn of loops can be optimized down to an empty function. A good compiler will notice that nobody except the local function can possibly know the location of the loop variables, their value is never used except for limiting the loop and therefore the whole loop has no effect and can be eliminated.
    And if your MCLK speed changes for some reason (maybe in a different project on an MSP with a faster crystal), the delay changes its duration even if the compiler does not optimize this code. And all you will see is that the previously working code is suddenly broken.

    You already have a trusted clock (from which you get your baudrate), so please us it in conjunction with a timer for making a delay.

    The delay before sending to the PC shouldn't be necessary - normally. 1ms (if it is 1ms) is 10 bytes! so you're dropping your effective throughput down to 1/6 of the 115200 Bd. And even much less, since you don't send to the PC and to the display simultaneously. But this would require asynchroneous handling with a send/receive buffer and ISRs.

    If your data is still too fast for hte PC, then the PC is too slow to receive the data. Well, 115200 shouldn't be a problem normally. I sometimes have 2 or 3 terminal windows open with 115200Bd data coming in. Plus some network connections. And I never had  a problem despite the fact that my PC is an old Athlon Xp. In fact I can compile in th e background and don't notice any character loss. But then, my connections are real RS232 connections, not routed through USB. Maybe there's a bottleneck.

  • I used your updated convert() and the conversion seems to work for the first 99 numbers, after that, it skips by 10 at 100.  There are also some numbers not displaying correctly (middle of the 3 digit numbers).  Same thing happens at numbers more than 999.

     

    1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
     31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 5
    7 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
    84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 110 111 112 113 114 115 116 117
    118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
    138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157
    158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177
    178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197
    198 199 1:0 1:1 1:2 1:3 1:4 1:5 1:6 1:7 1:8 1:9 220 221 222 223 224 225 226 227
    228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247
    248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267
    268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287
    288 289 290 291 292 293 294 295 296 297 298 299 2:0 2:1 2:2 2:3 2:4 2:5 2:6 2:7
    2:8 2:9 2;0 2;1 2;2 2;3 2;4 2;5 2;6 2;7 2;8 2;9 330 331 332 333 334 335 336 337
    338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357
    358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377
    378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397
    398 399 3:0 3:1 3:2 3:3 3:4 3:5 3:6 3:7 3:8 3:9 3;0 3;1 3;2 3;3 3;4 3;5 3;6 3;7
    3;8 3;9 3<0 3<1 3<2 3<3 3<4 3<5 3<6 3<7 3<8 3<9 440 441 442 443 444 445 446 447
    448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467
    468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487
    488 489 490 491 492 493 494 495 496 497 498 499 4:0 4:1 4:2 4:3 4:4 4:5 4:6 4:7
    4:8 4:9 4;0 4;1 4;2 4;3 4;4 4;5 4;6 4;7 4;8 4;9 4<0 4<1 4<2 4<3 4<4 4<5 4<6 4<7
    4<8 4<9 4=0 4=1 4=2 4=3 4=4 4=5 4=6 4=7 4=8 4=9 550 551 552 553 554 555 556 557
    558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577
    578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597
    598 599 5:0 5:1 5:2 5:3 5:4 5:5 5:6 5:7 5:8 5:9 5;0 5;1 5;2 5;3 5;4 5;5 5;6 5;7
    5;8 5;9 5<0 5<1 5<2 5<3 5<4 5<5 5<6 5<7 5<8 5<9 5=0 5=1 5=2 5=3 5=4 5=5 5=6 5=7
    5=8 5=9 5>0 5>1 5>2 5>3 5>4 5>5 5>6 5>7 5>8 5>9 660 661 662 663 664 665 666 667
    668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687
    688 689 690 691 692 693 694 695 696 697 698 699 6:0 6:1 6:2 6:3 6:4 6:5 6:6 6:7
    6:8 6:9 6;0 6;1 6;2 6;3 6;4 6;5 6;6 6;7 6;8 6;9 6<0 6<1 6<2 6<3 6<4 6<5 6<6 6<7
    6<8 6<9 6=0 6=1 6=2 6=3 6=4 6=5 6=6 6=7 6=8 6=9 6>0 6>1 6>2 6>3 6>4 6>5 6>6 6>7
    6>8 6>9 6?0 6?1 6?2 6?3 6?4 6?5 6?6 6?7 6?8 6?9 770 771 772 773 774 775 776 777
    778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797
    798 799 7:0 7:1 7:2 7:3 7:4 7:5 7:6 7:7 7:8 7:9 7;0 7;1 7;2 7;3 7;4 7;5 7;6 7;7
    7;8 7;9 7<0 7<1 7<2 7<3 7<4 7<5 7<6 7<7 7<8 7<9 7=0 7=1 7=2 7=3 7=4 7=5 7=6 7=7
    7=8 7=9 7>0 7>1 7>2 7>3 7>4 7>5 7>6 7>7 7>8 7>9 7?0 7?1 7?2 7?3 7?4 7?5 7?6 7?7
    7?8 7?9 7@0 7@1 7@2 7@3 7@4 7@5 7@6 7@7 7@8 7@9 880 881 882 883 884 885 886 887
    888 889 890 891 892 893 894 895 896 897 898 899 8:0 8:1 8:2 8:3 8:4 8:5 8:6 8:7
    8:8 8:9 8;0 8;1 8;2 8;3 8;4 8;5 8;6 8;7 8;8 8;9 8<0 8<1 8<2 8<3 8<4 8<5 8<6 8<7
    8<8 8<9 8=0 8=1 8=2 8=3 8=4 8=5 8=6 8=7 8=8 8=9 8>0 8>1 8>2 8>3 8>4 8>5 8>6 8>7
    8>8 8>9 8?0 8?1 8?2 8?3 8?4 8?5 8?6 8?7 8?8 8?9 8@0 8@1 8@2 8@3 8@4 8@5 8@6 8@7
    8@8 8@9 8A0 8A1 8A2 8A3 8A4 8A5 8A6 8A7 8A8 8A9 990 991 992 993 994 995 996 997
    998 999 9:0 9:1 9:2 9:3 9:4 9:5 9:6 9:7 9:8 9:9 9;0 9;1 9;2 9;3 9;4 9;5 9;6 9;7
    9;8 9;9 9<0 9<1 9<2 9<3 9<4 9<5 9<6 9<7 9<8 9<9 9=0 9=1 9=2 9=3 9=4 9=5 9=6 9=7
    9=8 9=9 9>0 9>1 9>2 9>3 9>4 9>5 9>6 9>7 9>8 9>9 9?0 9?1 9?2 9?3 9?4 9?5 9?6 9?7
    9?8 9?9 9@0 9@1 9@2 9@3 9@4 9@5 9@6 9@7 9@8 9@9 9A0 9A1 9A2 9A3 9A4 9A5 9A6 9A7
    9A8 9A9 9B0 9B1 9B2 9B3 9B4 9B5 9B6 9B7 9B8 9B9 1110

  • Ah, yes. digit needs to be reset to 0 after writing to *dest.

    Originally, the code was just an example stub with the 1000 while, then I thought I could as well extend it to cover the other digits as well. But I forgot to re-initialize the digit count when hopping to the next digit. This gives the following digits a 'head start' ;) (and of course once it reaches a value >9 it will start showing non-number values).

    Note, that directly typed this code for this thread. I never tried to compile it myself. I'm surprised that there weren't more typos. ;)

  • Thanks for spending time answering my questions.  That fixed the problem.

    I also found the delay() problem.  The battery was low!  That was a hard one to find.

    After putting a new set of batteries, the delay statement is no longer needed.

    Thanks a lot.

  • Shang Wu said:
    After putting a new set of batteries, the delay statement is no longer needed.

    Ah, so the additional current caused by the dat aline transitions (that's more than jsut holdind the line level) caused the battery to break down below a critical threshold.

    Indeed a hard-to-find cause.

**Attention** This is a public forum