When I activate TIMER1 ... , serial com. stops working [SOLVED]

Hello,,,

I've been coding some program for my robot.

My robot is an aquatic droid who is controlled by a GSM mobile, and wears a GSM shield.

The GSM shield is working its serial com. at 19200 bps.

My program, reads and writes to the shield with an emulated software serial.

My emulated software serial, is a just one more implementation of the serial com. in software, without using a chip for UART.

So, I've been reading the code of Robin2, which has an implementation of a simple software serial.

The problem is not to be with the Robin2's software.

My program is working ok, even changing timings and so on on timer 0 & 2. (Oh, I've implemented that program in pure C for AVR).

I am using an ATMEGA328P, and using internal timers.

Timer 0, is for serial rx.

Timer 1, is for controlling the servo. Sending the pulse, and refreshing it every 20ms.

Timer 2, is for serial tx.

RX & TX are working okay, even sending infinite AT commands to the GSM shield, and reading the responses of OK.

When I activate the Timer1, servo is pulsing and refreshing ok. But serial com. is missing bits on rx, and maybe in tx also...

Please, can you revise my code and tell me the improvements that are need to it, for just making everything to work in a good harmony?

Thanks,

just a reader & an arduino's fan.

My name is Abel, nice to meet you.

int main (void)
{
  // set pin of gsm rx to input_pullup
  DDRD  &= ~_BV(DDD3);   // set pin 3 to input
  PORTD |=  _BV(PORTD3); // activate pull-up resistor

  // set pin of gsm tx to output
  DDRD  |= _BV(DDD4);   // set pin 4 as output
  PORTD |= _BV(PORTD4); // set output to high on pin 4

  // set pin of gsm pwr to output
  DDRD  |= _BV(DDD5);

  // set pin of gsm rst to output
  DDRD  |= _BV(DDD6);

  // set pin of motor's relay to output
  DDRD  |= _BV(DDD7);

  // set pin of servo-direction to output
  DDRB  |= _BV(DDB0);
  PORTB &= ~_BV(PORTB0);

  // set pin of servo-dropper to output
  DDRB  |= _BV(DDB1);

  // setup timer0
  TCCR0A |= _BV(WGM01); // CTC mode

  // setup timer1
  TCCR1B |= _BV(WGM12) | _BV(CS10) | _BV(CS11); // CTC mode - prescaler /64 - start timer
  TIMSK1 |= _BV(OCIE1A); // enable int.
  OCR1A = 4999; // set to 20ms (refresh)

  // setup timer2
  TCCR2A |= _BV(WGM21); // CTC mode

  // setup int1
  EICRA |= _BV(ISC11); // falling edge

  // start UART serial com.
#if defined(DEBUG) || defined(FIXMODE)
  uart_init(UART_BAUD_SELECT(SERIAL_BAUDRATE, F_CPU));
#endif

  // enable g.ints
  SREG |= _BV(7);

  dbg("\r\nHello from APV3!\r\n\r\n\r\n")

#if defined(FIXMODE)
  fixmode();
#endif

  EIMSK |= _BV(INT1);  // enable INT1
  EIFR  |= _BV(INTF1); // clear int1

  //gsm_pwr(); // power on GSM module

  // read all the input buffer from gsm by rx serial com. emulation.
  gsm_read_resp(0);
  gsm_print_resp()
  gsm_read_resp(0);
  gsm_print_resp()
  gsm_read_resp(0);
  gsm_print_resp()
  gsm_read_resp(0);
  gsm_print_resp()

  do {
    gsm_send_cmd("AT");
    gsm_read_resp(0);
    gsm_print_resp()
  } while (1);
}

ISR(INT1_vect) {
  EIMSK &= ~_BV(INT1); // disable INT1 int.
  timer0_handler = rx_bit0;
  rxbyte = 0;
  OCR0A = 105; // set ticks
  TIMSK0 |= _BV(OCIE0A); // enable int.
  TCCR0B |= _BV(CS01); // prescaler: /8 - start
}

ISR(TIMER0_COMPA_vect) {
  OCR0A = 104; // update ticks
  rxbit = PIND & _BV(PORTD3);
  rxbit = rxbit >> 3;
  timer0_handler();
  rxbyte += rxbit;
}

ISR(TIMER1_COMPA_vect) {
  if (servo_pulsebegan) {
    PORTB &= ~_BV(PORTB0); // end pulse - set pin to LOW
    servo_pulsebegan = 0;
    OCR1A = 4999; // update ticks for refresh - 20ms
  } else {
    PORTB |= _BV(PORTB0); // begin pulse - set pin to HIGH
    servo_pulsebegan = 1;
    OCR1A = ( (F_CPU / 64) * (5.15 * dir + 1391.5) / 1000000UL ) - 1;//servo_ticks (dir); // update ticks for pulsing
  }
}

ISR(TIMER2_COMPA_vect) {
  OCR2A = 104; // update ticks
  timer2_handler();
  if (txbit) {
    PORTD |= _BV(PORTD4);
  } else {
    PORTD &= ~_BV(PORTD4);
  }
}

I hope you have enough code upside. If you need more, please ask me.

Thanks.

Complicated code like you have posted needs an extensive explanation unless someone is prepared to spend hours trying to figure out what it is trying to do. You also have the problem that people can't compile it and try it with the Arduino IDE.

RX & TX are working okay, even sending infinite AT commands to the GSM shield, and reading the responses of OK.

When I activate the Timer1, servo is pulsing and refreshing ok. But serial com. is missing bits on rx, and maybe in tx also...

This is confusing. Have you two different versions of software serial - my version using Timer2 (which, I think, you say is working) and another version - perhaps the standard version?

OR do you mean by "serial com" the hardware serial USB connection to the PC?

Give us a full description of the whole project - what all the parts (hardware and software) are and what is connected to what.

...R

No, I have no a official software serial implemented. I just took your code and made some changes.

Instead of TIMER2 only for TX and RX, I am using TIMER0 for RX and TIMER2 for TX. But the code is based on an idea which came from your code.

No, I am not using hardware serial, I am using pin 3 and pin 4. And also INT1 for detecting the start bit from GSM module.

The thing is that the communication works, but when I activate the TIMER1 interrupt (which code is upside), the serial communication with GSM module becomes unstable. - I think it's loosing bits, due to the high load of the TIMER1 ISR.

Do you understand me now? Hope yes.

Please, don't hesitate to ask for more if you need it.

Thanks for the answer. That was a pleasure, as always.

Even if compilable for Arduino IDE, people don't have my robot. And I don't think they would connect a servo, and a GSM module to an ATMEGA328P just for helping me...

I found the problem:

( (F_CPU / 64) * (5.15 * dir + 1391.5) / 1000000UL ) - 1

this seems to be a very heavy load. I'll try to improve it.

Keep reading,

thanks.

abel.

I can't believe, I made a first beta release of my aquatic robot... <3.

Just fixed it with a lookup table, converting angles (as indexes) to ticks.

thanks anyway. this is solved.