Go Down

Topic: Software Serial and Servo (Read 6517 times) previous topic - next topic

AndrewSimps4

Ok, so I know this has been a common problem for people when using the software serial and a servo at the same time. I have been trying and trying all day and I still can't get it to work. When I run the program the servo just starts going crazy! Any idea of what I need to do to fix this? Thanks.

AWOL

Quote
Any idea of what I need to do to fix this?

Showing us your code and a schematic would be a great start.

HazardsMind


AndrewSimps4

I have my gps in pin 10, 5v, and ground. My servo is in pin 9,5v, and ground. My code is basic tinyGps with the servo running.

HazardsMind

The arduino is not able to provide the amount of power the servo needs to work. So you need to get an external power source to power the servo. Get 4xAA batteries, that should be enough. NOTE: make sure the ground ( - ) is connected to the GND pin on the arduino!

AndrewSimps4

I tried everything and nothing is working . I was thinking maybe you could turn the software serial pin off with the end() function then turn the servo pin on And when your need the data from the software serial pin you could turn that on and the servo off. Would this work? And how would you turn the servo pin off?

Robin2

Did the suggestion in Reply #2 work?

Another option might be my simple yet another software serial.

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

abeltomillo

hello,

i can't get working sss.ino with my freaduino pro mini, it is arduino pro mini 5v atmega328 compatible. i can receive data, but responses after writing are unreadable... thanks.

Robin2


hello,

i can't get working sss.ino with my freaduino pro mini, it is arduino pro mini 5v atmega328 compatible. i can receive data, but responses after writing are unreadable... thanks.


I don't have a freaduino pro mini so I can't help directly. Does it use an Atmega328 chip?

Do you have a link to the details for the device?

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

TomGeorge

Hi, Andrew,

Please post your sketch and use code tags.. See section 7 http://forum.arduino.cc/index.php/topic,148850.0.html
Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png or pdf?

Tom..... :)
Everything runs on smoke, let the smoke out, it stops running....

abeltomillo



hello,

i can't get working sss.ino with my freaduino pro mini, it is arduino pro mini 5v atmega328 compatible. i can receive data, but responses after writing are unreadable... thanks.


I don't have a freaduino pro mini so I can't help directly. Does it use an Atmega328 chip?

Do you have a link to the details for the device?

...R


Hello R!!!

Thanks for the answer, really.

First tell you that I've solved the problem, thanks to your idea of serial implementation in arduino. What I did is to read and re-read until I got the idea of making my own serial communication for that device.

Answering your question, yes, it does have an atmega328. It's arduino pro mini like.

Now my servo and my GSM module are working together, just by using Timer1 interrupt for servo refresh and sending my own pulses to serial port and digital pin of servo ;)

thanks a lot for the answer, and hope you are ok.

I finish just saying that your program (sss.ino) didn't worked on that device, at least the TX code, since RX was ok ;)

cheers.

Robin2



First tell you that I've solved the problem, thanks to your idea of serial implementation in arduino. What I did is to read and re-read until I got the idea of making my own serial communication for that device.



That's good. Can you post your code so other people can benefit from your efforts?

I'm also interested to learn what you had to do differently from my code.

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

abeltomillo

#12
Sep 05, 2014, 09:17 pm Last Edit: Sep 05, 2014, 09:23 pm by abeltomillo Reason: 1



First tell you that I've solved the problem, thanks to your idea of serial implementation in arduino. What I did is to read and re-read until I got the idea of making my own serial communication for that device.



That's good. Can you post your code so other people can benefit from your efforts?

I'm also interested to learn what you had to do differently from my code.

...R


What I did from your code is to get the idea of making by my own an implementation for a serial communication in 9600 bauds. I could't take profit of so much more than the great concept. The code is completely different, since I only use a Timer1 with an arduino's library. (TimerOne.h from arduino.cc) for refreshing the servo, and no interrupts or INT1 & others for serial communication.

Yes, I want to publish the code, but I'm pasting only the core of processes...

tx_delay and rx_delay may be the same, as no other process things should be done while sending or receiving, but anyway you can call intermediate functions which should waste same time on each call, and reduce the delays... also if suffering lot of trash in transmission, just uncomment interrupt disable&enable and it would work fine.


here the core of serial communication at 9600 bauds.

Code: [Select]
int rx_delay = 105, tx_delay 105; // this is based on your mathematical calculations, R. And can be modified: 1000000/baud_rate + 1. In my case 105 uS for 9600 bauds.

void gsm_rx() {
 
 //noInterrupts();
 
 boolean _bit = rbi(PINB, 3);
 
 rx_byte = 0;
 
 if (_bit == false) {
   delayMicroseconds(rx_delay);
   _bit = rbi(PINB, 3);
   rx_byte = rx_byte | (_bit << 0);
   
   delayMicroseconds(rx_delay);
   _bit = rbi(PINB, 3);
   rx_byte = rx_byte | (_bit << 1);
   
   delayMicroseconds(rx_delay);
   _bit = rbi(PINB, 3);
   rx_byte = rx_byte | (_bit << 2);
   
   delayMicroseconds(rx_delay);
   _bit = rbi(PINB, 3);
   rx_byte = rx_byte | (_bit << 3);
   
   delayMicroseconds(rx_delay);
   _bit = rbi(PINB, 3);
   rx_byte = rx_byte | (_bit << 4);
   
   delayMicroseconds(rx_delay);
   _bit = rbi(PINB, 3);
   rx_byte = rx_byte | (_bit << 5);
   
   delayMicroseconds(rx_delay);
   _bit = rbi(PINB, 3);
   rx_byte = rx_byte | (_bit << 6);
   
   delayMicroseconds(rx_delay);
   _bit = rbi(PINB, 3);
   rx_byte = rx_byte | (_bit << 7);
   
   delayMicroseconds(rx_delay);
 }
 
 //interrupts();
 
}

void gsm_tx_cmd(char *cmd) {
 for (int i = 0; cmd[i] != 0; i ++) {
   gsm_tx(cmd[i]);
 }
 gsm_tx('\r');
}

void gsm_tx_str(char *str) {
 for (int i = 0; str[i] != 0; i ++) {
   gsm_tx(str[i]);
 }
}

void gsm_tx(char _byte) {
 
 //noInterrupts();
 
 cbi(PORTB, 4);
 delayMicroseconds(tx_delay);
 
 boolean _bit = rbi(_byte, 0);
 if (_bit) {
   sbi(PORTB, 4);
 } else {
   cbi(PORTB, 4);
 }
 delayMicroseconds(tx_delay);
 
 _bit = rbi(_byte, 1);
 if (_bit) {
   sbi(PORTB, 4);
 } else {
   cbi(PORTB, 4);
 }
 delayMicroseconds(tx_delay);
 
 _bit = rbi(_byte, 2);
 if (_bit) {
   sbi(PORTB, 4);
 } else {
   cbi(PORTB, 4);
 }
 delayMicroseconds(tx_delay);
 
 _bit = rbi(_byte, 3);
 if (_bit) {
   sbi(PORTB, 4);
 } else {
   cbi(PORTB, 4);
 }
 delayMicroseconds(tx_delay);
 
 _bit = rbi(_byte, 4);
 if (_bit) {
   sbi(PORTB, 4);
 } else {
   cbi(PORTB, 4);
 }
 delayMicroseconds(tx_delay);
 
 _bit = rbi(_byte, 5);
 if (_bit) {
   sbi(PORTB, 4);
 } else {
   cbi(PORTB, 4);
 }
 delayMicroseconds(tx_delay);
 
 _bit = rbi(_byte, 6);
 if (_bit) {
   sbi(PORTB, 4);
 } else {
   cbi(PORTB, 4);
 }
 delayMicroseconds(tx_delay);
 
 _bit = rbi(_byte, 7);
 if (_bit) {
   sbi(PORTB, 4);
 } else {
   cbi(PORTB, 4);
 }
 delayMicroseconds(tx_delay);
 
 sbi(PORTB, 4);
 delayMicroseconds(tx_delay);

 //interrupts();
}

And here the core for updating the servo:
Code: [Select]

int pulsewidth = 928;

void ser_dir_refresh() {
 if (pulse_began) {
   cbi(PORTD, 4);
   pulse_began = false;
 } else {
   sbi(PORTD, 4);
   pulse_began = true;
 }
 if (pulse_began) {
   Timer1.setPeriod(pulsewidth);
 } else {
   Timer1.setPeriod(15000);
 }
}

Here the function for upgrading the pulsewidth, or in other words, to change the graduation in degrees:

Code: [Select]
pulsewidth = 5.15 * angle + 1391.5;


How last mathematical function works? Just use the function y = mx + n; n = (y2 - y1) / (x2 - x1). For getting the pulse range. This goes from:

Code: [Select]
#define ANGLE_MIN -90
#define ANGLE_MAX 90
#define PULSE_MIN 928
#define PULSE_MAX 1855


cheers. hope this helps a lot.

Robin2


Yes, I want to publish the code, but I'm pasting only the core of processes...


Why the "but" ?

I don't understand, after going to the trouble of writing serial code why you are not just using the Servo library?

OR why you can't use SoftwareSerial if you write your own Servo code?

Have you any ideas about why my code would not work for you - were you trying to use my code alongside your servo code?

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

TomGeorge

Hi,

Sorry guys

BUT WHOSE THREAD IS THIS? WHAT PROBLEM ARE WE TRYING TO SOLVE?

AndrewSimps4 I think has given up on us. (I don't blame him.)

Does abeltomil realize that he has hijacked a thread with what appears to me to be a totally different problem to the original OP.

Not happy Jan. (Australian joke)

Tom........ :)
Everything runs on smoke, let the smoke out, it stops running....

Go Up