Show Posts
Pages: [1] 2 3 ... 5
1  Using Arduino / Programming Questions / function for configuring serial port options on: July 28, 2013, 08:32:04 am
For any AVR experts out there,
I'm trying to build a function to allow a bit more capability than the standard serial.begin function of the Arduino IDE. I was wondering if this looks like I'm on the right track
Code:

#include <avr/io.h>

bool USARTbegin( int port, int baudRate, int dataBits, char parity, int stopBits )
{
if(port == 0)
{
int clockCPU;
int prescale;

//basic setup
UCSR0A = 0x20; //B00100000;
UCSR0B = 0x0C; //B0001100
UCSR0C = 0x06; //B0000110 default
//change bits per settings

//baud rate setting
prescale = ((( clockCPU / ( baudRate * 16 UL))) - 1)
UBRR0H = (prescale >> 8); //load upper 8 bits to high byte
UBRR0L = (prescale);      //load lower 8bits to low byte


//message databit setting
if(dataBits == 9)
{
UCSR0B = (1<<UCSZ02);
UCSR0C = (1<<UCSZ01) | (1<<UCSZ00);
}
else if(dataBits == 8)
{
UCSR0B = (0<<UCSZ02);
UCSR0C = (1<<UCSZ01) | (1<<UCSZ00);
}
else if(dataBits == 7)
{
UCSR0B = (0<<UCSZ02);
UCSR0C = (1<<UCSZ01) | (0<<UCSZ00);
}
else if(dataBits == 6)
{
UCSR0B = (0<<UCSZ02);
UCSR0C = (0<<UCSZ01) | (1<<UCSZ00);
}
else if(dataBits == 5)
{
UCSR0B = (0<<UCSZ02);
UCSR0C = (0<<UCSZ01) | (0<<UCSZ00);
}
else
{
return false;
}//end of data bit

//parity setting
if(parity == o || parity == O)
{
UCSR0C = (1<<UPM01) | (1<<UPM00);
}
else if(parity == e || parity == E)
{
UCSR0C = (1<<UPM01) | (0<<UPM00);
}
else if(parity == n || parity == N)
{
UCSR0C = (0<<UPM01) | (0<<UPM00);
}
else
{
return false;
}//end of parity

//stop bits
if(stopBits == 1)
{
UCSR0C = (0<<USBS0);
}
else if(stopBits == 2)
{
UCSR0C = (1<<USBS0);
}
else
{
return false;
}//end of stop bits

}//end of port number


return true;
}

I realize that reading 9 bits of data requires pulling 1 bit from one of the UCSR's then reading UBR. Right now I don't ever forsee using 9 bit data length.
One thing I cannot figure out from the mega datashett, how can you tell how many bytes are currently in the recieve buffer?
thanks
2  Using Arduino / Interfacing w/ Software on the Computer / serial read char string from serialmonitor on: March 27, 2013, 06:24:30 am
I've been having trouble getting the ArduinoMega to read a complete text string sent from the serial monitor into a char array. I've tried a few different ways to do it but it will loose 2-4 charachters off the end 90% of the time. I tried looking for answers but didn't find any that have worked. I tried one of Nick Gammon's examples with the same effect.

It is to ask for text strings from the user computer and store the strings in EEPROM for later use after restart.
Code:
bool interface()
{
  int l;
  int p;
  int pos = 0;
  int noBytes = 0;
  char inChar;
  char inData[128];
  boolean m = false;
  inbyte = Serial.read();
  if (inbyte == 'a'){
    Serial.println("CONFIGURE UNIT STREAM OUTPUT");
    //store 4 char stream ID at EEPROM 100-103;
    Serial.println("enter 4 letter stream indentifier");
    while( m == false){
      if(Serial.available() >= 4){ //also tried simply "> 0"
        inChar = Serial.read();
        switch(inChar){
        case '\n':
          inData[pos] = 0;

          Serial.println("you entered");
          for(int n=0; n<4; n++){
            Serial.print(inData[n]);
          }
          Serial.println();
          p = 100;
          for(int n=0; n<4; n++){
            EEPROM.write(p, inData[n]);
            p++;
          }
          Serial.flush();
          m = true;
          break;
        case '\r':
          break;     
        default:
          if(pos < 5){
            inData[pos] = inChar;
            pos++;
          }
          break; 
        }//end switch 
      }//end if available
    }//end while
    m = false;
If I enter "ABCD" and send I get back AB and sometimes despite having called Serial flush I get the CD part on the next entry step.
I also tried it this way. Sometimes this step works correctly, sometimes not.
Code:

 //store 10 char city state at EEPROM 104-113
    Serial.println("enter 10 letter city state");
    while( m == false){
      if(Serial.available() >= 10){
        delay(100);
        noBytes = Serial.available();
        l = 0;
        while(Serial.available() > 0){
          inData[l] = Serial.read();
          l++;
        }
        Serial.println("you entered");
        for(int n=0; n<10; n++){
          Serial.print(inData[n]);
        }
        Serial.println(); 
        int p = 104;
        for(int n=0; n<10; n++){
          EEPROM.write(p, inData[n]);
          p++;
        }
        Serial.flush();
        m = true;
      } 
    }

So are there any exaples of entering strings of text via serial monitor????
3  Using Arduino / Programming Questions / Re: conversion double float recieved to int? on: October 04, 2012, 09:07:06 am
So if I could take the 52 numerical bits into a long long int 64bit (or should I just work with the bytes in a second array), then read the 11 exponent bits into an int, sutract 1023 from it for the actual exponent. I would need to determine how many decimal places the exponent indicates shifting and add 4 more shifts to the right. This should be the trunication point of the real int number. Then I need to use those bits 37 places left for my interger and add the sign bit.

OK that said I've got my head confused. If I work with it all at the byte/bit level, would the sign bit be the leftmost bit in the lowest addressed byte in the array of 8 bytes making up the original float?
4  Using Arduino / Programming Questions / Re: conversion double float recieved to int? on: October 04, 2012, 08:17:08 am
So unless theres some way to convert with the bits themselves it sounds like I need a seperate PC program to work with the 64 bit floats. So after I do message order checking I'll have to pass the full message array to a PC to be changed to RTCM standard format or start with a different imbedded processor.

I was looking at the spec sheet for a AVR32UC which you can get with an FPU built in, but it looks like it is set up for 32 bit acess also.
5  Using Arduino / Programming Questions / Re: conversion double float recieved to int? on: October 04, 2012, 06:38:58 am
PaulS, that is the RTCM Special Commitee 104 standard for Earth Centered Earth Fixed antenna position cooordinates. I,m just trying to make the actual measurement fit into their critera.

So what your saying is there is no way to directly work with 64 bit numbers on the 8bit AVR MCU?

I was thinking of moving up to a 32bit AVR with built in FPU but I didn't want to spend on having custom circuit boards made untill I had figured out how to make it work on something I was somewhat familiar with.
6  Using Arduino / Programming Questions / Re: conversion double float recieved to int? on: October 04, 2012, 06:18:44 am
Paul S, I have a C++ ide that allows AVR projects I have played with a little. I also have downloaded ATMEL's IDE but haven't really begun looking into it yet.

Coding Badly, In practice I need to measure to approx +/- 4,000,000.0001 meters. So an INT number in the +/- 100,000,000,000

Also based on the measurement of this output I would say the 64bit float is normalized? A different meassage outputs radians which would be 0.xxxxxxxx and would be denormallized?
7  Using Arduino / Programming Questions / Re: conversion double float recieved to int? on: October 03, 2012, 08:59:01 pm
I am considering using a C++ compiler instead of the Arduino IDE because it alows using 64 bit double floats and 64 bit long long int. So I am thinking if I take a 64bit float, multiply it by 10000.0 to shift the decimal, then cast it to a 64 bit signed int, it should trunicate at the point of precision my application requires.

From there I am still trying to figure out what to do. I need the int to fit into a 38bit signed 2's complement type. Assuming the measurement should fit into the capability of 37 bits and a sign bit can I just pull the bytes from an array. Read the sign bit from the original 64 bit number and map it onto the 38th bit of the number I need to send? If it does fit into the 37 bit value segment then all other bits would be 0 anyway, right?

I need the 38 bit int to represent a measurement to .0001 meters. The device send this in a 64bit float value.

I really need some guidence here.
8  Using Arduino / Programming Questions / Re: conversion double float recieved to int? on: September 28, 2012, 05:55:34 pm
So am I understanding this right?

Do you
Code:
float misc = conv(&storedArrayName[0]); //where 0 is the first position of the 8 bytes

This reads 8 bytes and returns a float value to variable "misc" ? I'm not seeing where the array dn[] is initialized. Or does the "dn" mean something else?
9  Using Arduino / Programming Questions / Re: conversion double float recieved to int? on: September 28, 2012, 06:38:59 am
So the constant is "understood" to be 2000 by any device programmed to read the standard and the reading device will perform the conversion after it recieveds the interger value?

For the function do I pass the 8 bytes in like this?
Code:
for(int i=0; i<8; i++){
conv(&arrayName[i]);
}
So will this pass 8 bytes into the function and return the modified 4 bytes to array 0-3 to be read as a float type? I don't see how float f can be read out of the function.
10  Using Arduino / Programming Questions / conversion double float recieved to int? on: September 27, 2012, 09:23:37 pm
Here's my problem. Mt device sends masages with 64bit IEEE denormalized double float values. I can save the message bytes in an array. I have found a function on this forum that is supposed to take the 8 bytes and bring it down to 4 bytes floating type numbers. I'm a bit confused as to how to pass the bytes to the function. I am posting the function code from the forum below.
Code:
float conv(byte *dn)
{
    union {
        float f;
        byte b[4];
    } fn;   
    int expd = ((dn[7] & 127) << 4) + ((dn[6] & 240) >> 4);
    int expf = expd ? (expd - 1024) + 128 : 0;
    fn.b[3] = (dn[7] & 128) + (expf >> 1);
    fn.b[2] = ((expf & 1) << 7) + ((dn[6] & 15) << 3) + ((dn[5] & 0xe0) >> 5);
    fn.b[1] = ((dn[5] & 0x1f) << 3) + ((dn[4] & 0xe0) >> 5);
    fn.b[0] = ((dn[4] & 0x1f) << 3) + ((dn[3] & 0xe0) >> 5);

   return fn.f;
}


I also am trying to format the data to resend out in a RTCM format. This is also confusing as it states it should be a 38bit int but says it holds +/-13,743,895.3471meters.  How does an int type data hold fractional information?
11  Using Arduino / Programming Questions / sample sketch on: September 14, 2012, 06:15:08 am
This will compile and run and gives me the same basic result out of the serial monitor

I want to start at the array position 28, check to see if the byte is a 0x01 or 0x02
if it's 1h or 2h then check the byte 29 array positions later
if it's a 0x00 then that is a good 30 byte segment 
if the 30 bytes are good data then print the 30 bytes(for now, later save)
advance the next check to the next byte in the array past the printed 30 bytes

if the byte checked is not 0x01 or 0x02 then advance 1 position and start checking for 1h or 2h again.

Code:
unsigned long TimerA;

int c; //channels with data message 5D
int z = 150;
int countGPS;
int countGLO;
byte tempArray[] = {
  0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x00, 0x02,0x05,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x00, 0x01,0x08,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x00, 0x01,0x09,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x00, 0x02,0x03,0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08,0x09,0x10,0x11,0x12,0x13,0x14,0x15,0x16,0x17,0x18,0x19,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x00, 0x10,0x03};


void setup(){
  Serial.begin(115200);     // error reporting output
  Serial2.begin(115200);
}

bool Serial2_WaitForByte(byte* v)
{
  TimerA = millis();
  while ( Serial2.available() <=0)
  {
    if (millis()-TimerA >= 100UL){
      return false;
    }
  }
  *v = Serial2.read();
  return true ;
}

void inMessage()
{
  Serial.println("inMessage begin"); //debug
  int n;
  int i;

  for( n=28; n< z; n++){
    if(tempArray[n] == 0x01){  //glonass 30 bytes data good
      if(tempArray[n+29] == 0x00){
        for(int i=n; i<i+29; i++){
          Serial.println(tempArray[i]);
        }
        Serial.println("split");
        countGLO++;
      }  
    }
    if(tempArray[n] == 0x02){   //gps 30 bytes data good
      if(tempArray[n+29] == 0x00){
        for(int i=n; i<i+30; i++){
          Serial.println(tempArray[i]);
        }
        Serial.println("split");
        countGPS++;
      }
    }
  }
}

void loop(){
  Serial.println("loop start"); //debug
  inMessage();
}


12  Using Arduino / Programming Questions / Re: trying to parse a serial read array on: September 13, 2012, 05:10:52 pm
This is where I'm getting stuck. As far as sample data, any byte values will work in the data section but as an example:
(header data) 27 bytes any value, 0x00,     (first sat) 0x01, 0x08, 27 bytes any value, 0x00,      (second sat) 0x02, 0x08, 27 bytes any value, 0x00,     (end bytes) 0x10, 0x03.

I want to sort the satelite data by if they start with 0x01 or 0x02 and save the 30 bytes of data.

Code:

case F5saveData:   //go through tempArray

      for( n=28; n< z-30; n++){
        if(tempArray[n] == 0x01){  //glonass 30 bytes data good
          if(tempArray[n+29] == 0x00){
            for(int i=n; i<i+29; i++){
              Serial.println(tempArray[i]);
            }
            countGLO++;
          } 
        }
        if(tempArray[n] == 0x02){   //gps 30 bytes data good
          if(tempArray[n+29] == 0x00){
            for(int i=n; i<i+30; i++){
              //WriteF5hGPS(addr,i*8,tempArray[i]);
              Serial.println(tempArray[i]);
            }
             countGPS++;
          }
        }
      }
      state = Fini;
           break;
 
13  Using Arduino / Programming Questions / trying to parse a serial read array on: September 13, 2012, 04:09:35 pm
I need help again. I have the data being in a complete message in my tempArray[ ]. If I serial print the full tempArray I can see the message is complete and all of the byte segments are the correct length.

This message contains a header of 27 data bytes plus a 0x00 followed by 30 byte segments for each satelite. Each segment starts with either a 0x01 or 0x02 and each ends with a 0x00 byte.
I want to take the 30 byte segments and save them to an external FRAM but first I am trying to serial print ln the section of the array.
I am trying to check for the 1 or 2 at the beginning and then check for the 0 at the end of the segment. However when I run this I get 2 satelites worth of data then it just runs on collecting bytes forever. Where am I going wrong here?


Code:
case pF5sCollectTheData:  //header is 27 bytes, 1 null 0x00, message 30 per sv last byte of 30 is 0x00
      TimerA = millis();
      if(n<z){
        Serial2_WaitForByte(&inbyte);
        if(inbyte == 0x03){
          if(tempArray[n] == 0x10){
            n++;
            tempArray[n] = inbyte;
            z=n+1;                  //sets z for next phase to 1 byte past 0x03
            state = F5parse;
          }
          else{   //if not end byte advance and store in array
            n++;
            tempArray[n] = inbyte;
          }
        }
        else{
          n++;
          tempArray[n] = inbyte;
        }
      }
      else{
        TimerA = millis();
        state = F5parse;
      }
      if (millis()-TimerA >= 400UL){
        Serial.println("time out error F5collect data");
        state = Fini;
      }
      break;


    case F5parse:          //check for and remove double 0x10 bytes sent from device
      Serial.println("F5 parse begin");
      for(n=0; n<z; n++){
        if(tempArray[n] == 0x10 && tempArray[n+1] == 0x10){
          for(w = n; w < z; w++){
            tempArray[w] = tempArray[w+1]; //recopy all bytes after first 0x10
          }
          z=w+1;
        }
      }
      for(n=0; n<z; n++){
        if(tempArray[n] == 0x03 && tempArray[n-1] == 0x10){  //shorten any extra to end bytes
          z = n+1;
        }
      }
      Serial.println("entering F5 save data state");
      for(n=0; n<28; n++) {      //header info
        //WriteF5h(addr,n*8,tempArray[n]);
        Serial.println(tempArray[n]);
      }
      Serial.println("split");
      TimerA = millis();
      state = F5saveData;

      if (millis()-TimerA >= 400UL){
        Serial.println("time out errorF5 parse data");
        state = Fini;
      }
      break;



    case F5saveData:   //go through tempArray

      for( n=28; n< z-30; n++){
        if(tempArray[n] == 0x01){  //glonass 30 bytes data good
          if(tempArray[n+29] == 0x00){
            for(int i=n; i<i+29; i++){
              //WriteF5hGLO(addr,i*8,tempArray[i]);
              Serial.println(tempArray[i]);
            }
            Serial.println("split");
            countGLO++;
          } 
        }
        if(tempArray[n] == 0x02){   //gps 30 bytes data good
          if(tempArray[n+29] == 0x00){
            for(int i=n; i<i+30; i++){
              //WriteF5hGPS(addr,i*8,tempArray[i]);
              Serial.println(tempArray[i]);
            }
            Serial.println("split");
            countGPS++;
          }
        }
      }
      state = Fini;
      if (millis()-TimerA >= 400UL){
        Serial.println("time out errorF5 save data");
        state = Fini;
      }
      break;
14  Using Arduino / Networking, Protocols, and Devices / Re: u-blox gps lea-6h / Mega2560 on: September 09, 2012, 10:36:22 pm
You might want to check on the parity the gps chip uses for output. I recently have been working on a gps project using odd parity.
15  Using Arduino / Programming Questions / Re: best meathod to capture serial data? on: September 09, 2012, 04:08:43 pm
I appreiate the response.
I was just trying to debug it with this code.
Code:
case pF5sCollectTheData:  //header is 27 bytes, message 30 per sv no delimters 990bytes possible
      TimerA = millis();
      //  trial1
      Serial.println("entering F5 data collection state");
      while( messageF5 == false){
        for( n=0 ; n<800; n++){
          Serial2_WaitForByte(&tempArray[n]);
          if (tempArray[n] == 0x03 && tempArray[n-1] == 0x10){
            messageF5 = true;
            Serial.println("F5 complete in array");
          }
        }
      }
      if (messageF5 == true){
        n = 27;
        for(int b=0; b<8 ; b++){
          Serial.println(tempArray[n], DEC);
          Serial.println(tempArray[n+29], DEC);
          n = n + 30;
        }
        state = Fini;
      }
      break;

So I get an expected output for the first few satilites. Each segment has an unused byte that should always be 0 and each should start with a system ID 1,2, ect. So maybe I can search down the whole array finding the 1,2,ect and check to see if +29 bytes there is a 0. Based on that I should have very good odds that it would be a good segment.
Pages: [1] 2 3 ... 5