NerdKits - electronics education for a digital generation

You are not logged in. [log in]

NEW: Learning electronics? Ask your questions on the new Electronics Questions & Answers site hosted by CircuitLab.

Microcontroller Programming » TEXT output via serial / com

November 02, 2011
by bl00513
bl00513's Avatar

Hi Forum,

I work for a company that analyzes call data from PBX systems. In many cases we read in the data from a serial/com connection. The data we get from the PBX is very simple, usually single line, text. (e.g. 11/02 20:15 00:20:00 4567 18005551212 001 007 ...you get the idea.)

When we train / test the system we typically don't have a way to emulate this type of live data. We can import from files, but then it doesn't appear to us as streaming data and thus is not that useful for our purposes.

I want to program my nerd kit to output random text matching this format (or something similar) via a serial connection. I am have no problem generating the random text but outputting via serial is a foreign concept to me.

1.) I would love for someone to lead me on the correct path as far as sending data (especially text) over serial.

2.) How would I interface this? I know that the USB cable that ships with the kit is a serial interface. Can I send data to my COM port using this cable? I would assume so, but again I am not sure.

I've made pretty much zero progress on this as I really don't even know where to start. I am brand new to micro-controller programming, so don't feel like you are insulting me by telling me things I might already know. I appreciate, and won't turn down, any help. Also, I do not expect anyone to do this for me; I really do want to learn. Please know that I am asking for help, not expecting free labor. Thank you in advance to anyone who can offer assistance.

November 03, 2011
by hevans
(NerdKits Staff)

hevans's Avatar

Hi bl00513,

Doing serial communicatios out from the chip is fairly easy. We have a couple of examples of it in our video tutorials. I would recommend you take a look at our digital weigh scale, it sends its data back to the PC over the UART. The temp sensor project also sends its data back to the PC so you can look to that for an example.

Once you have data going back to your PC over UART you are halfway there. You are not going to be able to use the same cable because our cable does a serial to USB conversion before it makes it to the PC. However coming out of chip are the TX are RX lines that you are probably used to dealing with as part of your serial/COM protocol. You are going to have to do level shifting to get the signals coming out of the chips TX/RX pins to conform to the RS232 standard that your board expect (which will be a fun project in itself). Hope that points you in the right direction.

Humberto

November 03, 2011
by bl00513
bl00513's Avatar

Thanks a lot ! This really helps. I think I will be up and running soon. If I run in to any trouble, I will let you know.

November 05, 2011
by bl00513
bl00513's Avatar

OK, I'm working on testing my code using putty. I'm getting plenty of output, but it's streaming so fast I can't use the data. Does anyone have an easy method of putting a some time between each output? Also, I can't access the com port unless create a while loop and use uart read as my first command in the loop, followed by my output. Does anyone have a word around for this?

November 05, 2011
by Ralphxyz
Ralphxyz's Avatar

bl00513, couldn't you make a long loop on the mcu before doing your serial output?

You would have an embedded loop or two.

Ralph

November 05, 2011
by bl00513
bl00513's Avatar

Ralph, I think this would work. What would you suggest? Would something like this work?

int x = 0;
while (x <> 500)
{
x++;
}

Do you know if there is a way to equate this to a certain amount of time?

November 06, 2011
by Ralphxyz
Ralphxyz's Avatar

Hi bl00513, yes that loop would give you a delay, and yes someone who actually is a programmer could tell you how long of a delay, but not I.

Now is it important that you see live time output from your sensor or is a delay no problem?

Also or inconjunction with displaying live time data you ought to look at using Python instead of putty.

Using Python you could send your data to a excel spreadsheet or to a managed display on you monitor instead of the running display you see now in putty.

If you look at some of the Nerdkit tutorials you will get a good start in using Python.

If you really have a need of viewing sensor data on your pc often, it would be worth your time to learn Python.

Ralph

November 06, 2011
by bl00513
bl00513's Avatar

What I am trying to do is simulate SMDR data that a PBX would typically output. In all honesty, I really don't even have to physically "see" the data. I just need it to output on a COM. Since this data usually includes a time/date stamp in the record, delay is actually not a problem (so long as it is not streaming too fast).

Also, (a little off topic) is it possible to change the baud rate of UART? Right now I am using 115200. Is there a way to shift this down to a slower speed?

November 06, 2011
by bl00513
bl00513's Avatar

Never mind about changing baud rate; I found another thread that did a great job explaining it.

Aside from that, I remember using a delay function in one of the nerdkits tutorials. Does anyone know how I could apply that to my project?

November 06, 2011
by treymd
treymd's Avatar

There are a few delay functions that are part of the nerdkits library that offer a pretty accurate delay (If I remember correctly the drift is so small that you won't have an issue) I believe the functions are delay_ms(uint16_t milliseconds) and delay_us(uint16_t microseconds), with delay_ms(1000) being 1 second.

As far as changing the baud rate, I know that the default baud rate is determined by setting a prescaler(or divider or some jazz) to /128, presumably you can also divide by 256 and perhaps 1024 for lower baud rates??? My guess is that /256 will give you 57600 and /1024 will give you 14400. I'm just now getting to the datasheet section on the USART so thats the only guess/info I can provide just yet.

November 06, 2011
by treymd
treymd's Avatar

Heck I'll even take a crack at how long your while loop takes. there will need to be a clock cycle to compare x to 500, and another clock cycle to add to counter per loop. Maybe another clock cycle to jump back to the beginning of the loop? This is like a jellybean counting game. My guess is somewhere around 1500 clock cycles. Since we are clocking our MCU at 14,745,600Hz (14.7456MHz) that would be .000172 seconds.

November 06, 2011
by bl00513
bl00513's Avatar

Treymd,

Thanks! I think I am going to stick with trying to use the delay function so I can get a more precise delay. Also, good call on the baud rate. Everything else corresponds with what you are saying. As soon as I get the project a little more refined I will post the code I've got. I really appreciate everyone's help.

November 06, 2011
by bl00513
bl00513's Avatar

So below is what I have in my main. I am using an array and a while loop to generate a "random" extension number. If I do away with the array and simply used fixed strings I get output with no problem. When I add the array in and try to use %d in my strings I simply get nothing on putty. Any ideas, suggestions? Would I have to use pointers or something?

int main() {

  // init serial port
  uart_init();
  FILE uart_stream = FDEV_SETUP_STREAM(uart_putchar, uart_getchar, _FDEV_SETUP_RW);
  stdin = stdout = &uart_stream;

  // set PB2,PB3 as output
  DDRB |= (1<<PB2) | (1<<PB3);

  // init PWM
  pwm_init();

  uint16_t pos = PWM_START;

  //char tc; this will remain unused unless we enable uart_read()

  int extension[] = {100,101,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,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,200,201,202,203,204,205,206,207,208,209,210,211,212,213,
  214,215,216,217,218,219,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,300,301,302,303,304,305,306,307,308,309,310,311,312,313,314,315,316,317,318,319,320,321,322,323,324,
  325,326,327,328,329,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,400,401,402,403,404,405,406,407,408,409,410,411,412,413,414,415,416,417,418,419,420,421,422,423,424,425,426,427,428,429,430,431,432,433,434,435,
  436,437,438,439,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,500};

  int random(int n);
  int extarr = 0;
  int extnum = 0;

  while(1)  // a "random" number is generated to pull an array position from the extension array
  {
  extarr = random(400); //should this be 401 ?
  extnum = extension[extarr];
  }

  while(1) {

  // Wait for a character to be sent to the serial port.
  //tc = uart_read();  (this will also remain unused unless we enable the uart_read() funtion)

    int tempx = 0;

    while(tempx < 1000) {
    tempx++;

    }
    printf_P(PSTR("%d| 01|                   12039265400 |          | 09:10:18P | 00:00:05  |OUT \r\n"),extnum);
    printf_P(PSTR("%d| 01|                   19055072888 |          | 09:10:48P | 00:01:13  |OUT \r\n"),extnum);

  }

  return 0;
}
November 07, 2011
by hevans
(NerdKits Staff)

hevans's Avatar

Hi bl00513,

Looking at your code you seem to have two separate while(1) functions. A while(1) function is an infinte loop that will keep running forever (because 1 is always a logical true is C). In your code the program starts at the main() method and when it gets down to your first while loop it just keeps going there forever, it heve has a chance to get out to your print statements.

Humberto

November 07, 2011
by bl00513
bl00513's Avatar

Humberto, That makes perfect sense! I don't know why I did't see that before. I will make a few revisions to get this going. You guys are great; this forum is always so helpful.

November 08, 2011
by treymd
treymd's Avatar

As a follow up and because I was curious, I used AVR studio and the simulator to approximate the time the 500 cycle while loop takes to execute. I was way off with my initial guess. It actually takes 9510 cycles to complete (what I was missing is data being moved in and out of registers and memory, which added cycles.) So the answer is actually close to .6449 microseconds.

While I was experimenting I noticed that if I did not make the counter variable a volatile int, GCC actually got rid of the while loop altogether! I'm guessing that this was an "optimization"

Sorry about going off topic, but I found this to be an interesting experiment.

November 10, 2011
by bl00513
bl00513's Avatar

treymd,

What would the math behind that be? 1hz is = 1 clock p/second ??? So would the mcu do one clock in and one clock out for each 8 bits (is the mcu 8 bit)????

November 10, 2011
by bl00513
bl00513's Avatar

Also,

Looking at my code above (with out the errors)... does anyone see a better way to create a random number to pull from that array of extensions? As is I will almost get the same extension because the variable resets to 0 on each loop. Is there an actual function that generates a random number?

Post a Reply

Please log in to post a reply.

Did you know that signed numbers need to be sign-extended when chaging variable sizes? Learn more...