Pages: [1]   Go Down
Author Topic: software serial  (Read 1586 times)
0 Members and 1 Guest are viewing this topic.
Australia
Offline Offline
Full Member
***
Karma: 7
Posts: 209
AVR Microcontrollers
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

This is a serial data transmission class for my weather station.

http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1265087241

It has 3 functions:

SSERIAL.begin(int baud)
This sets the baud rate. The int baud sets the pulse width in microsecs.
If this function is not used a default pulse width of 2500 microsecs will
be set to give a baud rate 0f 400.

unsigned int SSERIAL.request()
This requests a remote audino to send in serial a unsigned integer.
If the remote does not respond in 1 second the function returns 65535.

void senddata(unsigned int send_data)
This waits for a request then sends in serial the unsigned integer .
There is no timeout.

I have a remote site to monitor weather data. This data is collected using an arduino pro.




My "master" station is indoors and uses a arduino 2009.
This arduino will request data from the remote arduino.

On receiving a request the remote will send an unsigned integer in serial.
All of my weather sensors produce unsigned integers.
The class uses software serial. It operates in the same manner as
SoftwareSerial library in the arduino-0017.

I have included a timeout which is used to produce an error message
at the master.

The remote send the serial data from its D3.
It listens on D2 for the request (LOW).

The master sends the request (LOW) from D3.
It listens for serial data on D2.

The following details apply to windows:

To try out this class you will need to store the SSERIAL folder in:

C:\arduino-0017\hardware\libraries

Or where you have your arduino-0017.

Start arduino-0017 and look under file-examples.

Select master for your main arduino.
Upload it to the port it is allocated - mine was COM8.

Code:
/*    Serial data transfer of an unsigned integer from a remote arduino.
      This is the master arduino
      SSERIAL.begin(baud);  sets up the baud speed for serial transmission
      SSERIAL.request() send request to remote arduino.
      Then it waits for an unsigned integer to be sent back in serial.
      Returns 65535 if times out after 1 second.
      The request is sent (LOW) on D3.
      The data is received on D2.
*/

#include <SSERIAL.h>

int baud = 100;   //the pulse width of the serial data
unsigned int rec_data = 0;  //the integer received
void setup()   // run once, when the sketch starts
{
 Serial.begin(9600);      // initialize serial communication with computer
 SSERIAL.begin(baud);   // set transmission baud rate default = 400
}

void loop()                     // run over and over again
{
 rec_data = SSERIAL.request();
 Serial.println(rec_data);  //print the data from remote
 delay(100);
}//end of loop


Start another instance of arduino-0017 and look under file-examples.

Select slave for your slave arduino.
Upload it to the port it is allocated - mine was COM9.

Code:
/*    Serial data transfer of an unsigned integer from a remote arduino.
      This is the slave arduino
      SSERIAL.begin(baud);  sets up the baud speed for serial transmission
      SSERIAL.senddata(send_data); Waits until request for data no timeout.
      when it gets request it sends send_data in serial to master.
      D2 is polled for request (LOW).
      Data is sent on D3.
*/

#include <SSERIAL.h>

unsigned int send_data = 30555;  //the integer to send
const int baud = 100;   //the pulse width of the serial data

void setup()            // run once, when the sketch starts
{
 SSERIAL.begin(baud);    // set transmission baud rate default = 400
}

void loop()                     // run over and over again
{
  SSERIAL.senddata(send_data);   //sends data when requested
}//end of loop


There is also another example you can use for the master.
master_error
This will check groups of 100 data transfers and print out the number
of errors.

Code:
/*    Serial data transfer of an unsigned integer from a remote arduino.
      This is the master arduino
      SSERIAL.begin(baud);  sets up the baud speed for serial transmission
      SSERIAL.request() send request to remote arduino.
      Then it waits for an unsigned integer to be sent back in serial.
      Returns 65535 if times out after 1 second.
      The request is sent (LOW) on D3.
      The data is received on D2.
*/

#include <SSERIAL.h>

int baud = 100;   //the pulse width of the serial data
//anything faster than this gives large error rate
unsigned int rec_data = 0;  //the integer received
void setup()   // run once, when the sketch starts
{
 Serial.begin(9600);      // initialize serial communication with computer
 SSERIAL.begin(baud);   // set transmission baud rate default = 400
}

void loop()                     // run over and over again
{
 unsigned int temp = 0;
 unsigned int errors = 0; //number of errors
 byte j = 0;   // for start counter
 for (j = 0; j < 100 ; j +=1)   //get 100 data transfers
 {
 temp = SSERIAL.request();  //get an integer transfer
 if (temp != 30555)
 {
 //Serial.println(temp);  
 errors +=1;  //we have an error
 }//end of != 30555
 delay(1);
 }//end of get 100 data transfers
 Serial.println(errors);
 delay(1);
}//end of loop


With a pulse width of 100 microsecs there should never be any errors.
If you decrease the pule width(increase baud rate) you will find that
errors start to occur.

Below 80 it drops its bundle. The same happens for SoftwareSerial
there is too much slop in the timing when using software.

The new programs and diagrams are available from:
Download SERIAL.zip


http://sourceforge.net/projects/arduinoweather/files/
« Last Edit: March 08, 2010, 04:27:22 pm by carl47 » Logged

0
Offline Offline
Full Member
***
Karma: 4
Posts: 218
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

explain please why normal serial cannot be used to send an unsigned integer. I don't understand why you need this?
Is it just alearner foryou or do we need it to?
« Last Edit: March 09, 2010, 05:26:58 am by april.steel » Logged

UK
Offline Offline
Faraday Member
**
Karma: 16
Posts: 2883
Gorm deficient
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

A couple of thing:
It's usual to capitalise macros, thus

Code:
#define SETUP_D3 DDRD |= 0x08

And it's best to leave semicolons off macros:
Code:
#define setupD3 DDRD |=0x08[glow];[/glow]

They will bite you on the bottom sooner or later.

april has a good point: Why not send and receive as two bytes?There'd be less chance of corruption due to accumulated sampling time error, because you'd allow the receiver to resychronise for each byte.
« Last Edit: March 09, 2010, 06:30:06 am by GrooveFlotilla » Logged

Per Arduino ad Astra

Australia
Offline Offline
Full Member
***
Karma: 7
Posts: 209
AVR Microcontrollers
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

April

Thanks for your reply.

You certainly do not need this as well as softwareserial for general serial work.

Serial software is not a hard task and I did write it at first for my own learning experience. When it started getting timing problems at high speeds I checked softwareserial.

If you send an unsigned integer it gets sent through:

Quote
void SoftwareSerial::printNumber(unsigned long n, uint8_t base)
{
  unsigned char buf[8 * sizeof(long)]; // Assumes 8-bit chars.
  unsigned long i = 0;

  if (n == 0) {
    print('0');
    return;
  } 

  while (n > 0) {
    buf[i++] = n % base;
    n /= base;
  }

  for (; i > 0; i--)
    print((char) (buf[i - 1] < 10 ? '0' + buf[i - 1] : 'A' + buf[i - 1] - 10));
}


You then have to do the reverse to get at your integer.

You can split up the integer at the start and use two:

Quote
void SoftwareSerial::print(char c)
{
  print((uint8_t) c);
}


Then combine the two to get the integer.

My application must have a timeout. I could have modified softwareserial I suppose.

As I aready had a working send integer that I liked I incorporated mine in my weather program.
I put it on forum because some are following the weather program and I wont to keep it complete.

Groove

Thanks for your reply.

My ANSI C programming text does not specify upper case for the C preprocessor.
In fact it uses lower case in its examples (p88 Kernighan & Ritchie).
My C++ text does not specify either but it does use capitals in its examples(p900 Deitel).

I have been absent from the scene for some time so I will accept your
statement that it is "usual" to use capitals.

You are dead right about the   ;  
That slipped through as the compiler can cope with   ;;

I will watch that in future.
« Last Edit: March 11, 2010, 03:46:32 pm by carl47 » Logged

0
Offline Offline
Full Member
***
Karma: 0
Posts: 126
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code conventions are never consensual smiley

But when looking at code, you should have at least an idea of what a certain word stands for. Let's see some examples:

WHOAMI(X) <-- WHOAMI is a preprocessor macro
WhoAmI(X) <-- WhoAmI(X) is the constructor of WhoAmI class.
whoAmI(X) <-- whoAmI(X) is a function.

WHOAMI <--  is a macro
WhoAmI <-- is a class name
whoAmI <-- is a variable.

Álvaro
Logged

Australia
Offline Offline
Full Member
***
Karma: 7
Posts: 209
AVR Microcontrollers
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Very good.

I use C++ for programmers by P.J.Dettel (2009).

He does use all the above ,as you say, except cant we name variables
in lower case ?
Logged

Pages: [1]   Go Up
Jump to: