Porting Arduino UNO code to Arduino MEGA 2560

Hello,

I'm trying to make a trackuino shield work on arduino mega for a HAB project , I need more ram and flash, but it doesn't work.

In the aprslib.zip is the library.

I think that the only "low level" code is in afsk_avr files and I don't understand what it's doing exactly.

Can anyone help me?

Best regards and thanks in advance

aprslib.zip (23.7 KB)

What is a "trackuino shield"?
What is "HAB"?
What is the purpose of the aprslib library?
How do you know it is not working?

  • If it won't compile then post the error message
  • If it compiles but does not work properly tell us what actually happens and what should happen.

...R

Robin2:
What is a "trackuino shield"?

An arduino shield intended to provide APRS communication to Arduino UNO http://www.trackuino.org/

Robin2:
What is "HAB"?

High Altitude Balloon High-altitude balloon - Wikipedia

Robin2:
What is the purpose of the aprslib library?

Provide a library for easy APRS communication with Arduino.

Robin2:
dd
How do you know it is not working?

  • If it won't compile then post the error message
  • If it compiles but does not work properly tell us what actually happens and what should happen.

It compiles, but It doesn't send any signal through PWM pins.

I think that the problem is in afsk_avr.h and afsk_avr.cpp files, there are some functions with low level registers and timers that I don't understand.

I'm not sure you are really trying to help us to help you.

What is APRS?

Can you post the program that does not work? I do not want to download an unknown ZIP file.

...R

Robin2:
I'm not sure you are really trying to help us to help you.

What is APRS?

We use 2m amaterur radio packet system to send messages, you can read more info at Automatic Packet Reporting System - Wikipedia

Robin2:
Can you post the program that does not work? I do not want to download an unknown ZIP file.

The zip file is the entire library, of course I can post the files where I think is the problem.

afsk_avr.cpp (6.24 KB)

afsk_avr.h (1.88 KB)

xload:
you can read more

I don't have any interest in the subject beyond the minimum required to help you get your program working so I am hoping you will convey the necessary information in a concise paragraph or two.

The zip file is the entire library, of course I can post the files where I think is the problem.

Before even considering the library we need to see your program that is using the library. And as you have some idea (which may be quite correct) about where the problem lies please explain how you come to that conclusion.

...R

A lot of thanks Robin2

I wrote the library from the original code, the original code was a arduino sketch with a lot of cpp and h files, to handle it better I decided write a library with this functions:

  • begin(CALLSIGN)
  • aprs_send(time, latitude, longitude, course, speed, comment)

Also I'm working on latitude and longitude conversion functions (APRS needs some special formats)

It works fine on Arduino UNO, It was originally designed for this plataform, but I think that is a good idea get working on Arduino MEGA 2560 because some High Altitude Balloons need a lot os sensors and Arduino UNO is not is not enough, HABs usually work with temperature, pressure, altitude sensors, GPS, GSM, much more and now APRS.

I think that the problem is in afsk_avr.h and afsk_avr.cpp because I see code working with pins at low level format like here:

afsk_avr.h

#if AUDIO_PIN == 3
#  define OCR2 OCR2B
#endif
#if AUDIO_PIN == 11
#  define OCR2 OCR2A
#endif

afsk_avr.cpp

void afsk_timer_setup()
{
  // Set up Timer 2 to do pulse width modulation on the speaker
  // pin.
  
  // Source timer2 from clkIO (datasheet p.164)
  ASSR &= ~(_BV(EXCLK) | _BV(AS2));
  
  // Set fast PWM mode with TOP = 0xff: WGM22:0 = 3  (p.150)
  // This allows 256 cycles per sample and gives 16M/256 = 62.5 KHz PWM rate
  
  TCCR2A |= _BV(WGM21) | _BV(WGM20);
  TCCR2B &= ~_BV(WGM22);
  
  // Phase correct PWM with top = 0xff: WGM22:0 = 1 (p.152 and p.160))
  // This allows 510 cycles per sample and gives 16M/510 = ~31.4 KHz PWM rate
  //TCCR2A = (TCCR2A | _BV(WGM20)) & ~_BV(WGM21);
  //TCCR2B &= ~_BV(WGM22);
  
#if AUDIO_PIN == 11
  // Do non-inverting PWM on pin OC2A (arduino pin 11) (p.159)
  // OC2B (arduino pin 3) stays in normal port operation:
  // COM2A1=1, COM2A0=0, COM2B1=0, COM2B0=0
  TCCR2A = (TCCR2A | _BV(COM2A1)) & ~(_BV(COM2A0) | _BV(COM2B1) | _BV(COM2B0));
#endif  

#if AUDIO_PIN == 3
  // Do non-inverting PWM on pin OC2B (arduino pin 3) (p.159).
  // OC2A (arduino pin 11) stays in normal port operation: 
  // COM2B1=1, COM2B0=0, COM2A1=0, COM2A0=0
  TCCR2A = (TCCR2A | _BV(COM2B1)) & ~(_BV(COM2B0) | _BV(COM2A1) | _BV(COM2A0));
#endif
  
  // No prescaler (p.162)
  TCCR2B = (TCCR2B & ~(_BV(CS22) | _BV(CS21))) | _BV(CS20);

  // Set initial pulse width to the rest position (0v after DC decoupling)
  OCR2 = REST_DUTY;
}

void afsk_timer_start()
{
  // Clear the overflow flag, so that the interrupt doesn't go off
  // immediately and overrun the next one (p.163).
  TIFR2 |= _BV(TOV2);       // Yeah, writing a 1 clears the flag.

  // Enable interrupt when TCNT2 reaches TOP (0xFF) (p.151, 163)
  TIMSK2 |= _BV(TOIE2);
}

void afsk_timer_stop()
{
  // Output 0v (after DC coupling)
  OCR2 = REST_DUTY;

  // Disable playback interrupt
  TIMSK2 &= ~_BV(TOIE2);
}

I think that here is the reason why I don't detect any output on 3 or 4 Arduino MEGA 2560 pins 3 or 4 of 2560, but I don't know how to fix it.

One thing I see very quickly is that the library is using the 8 bit Timer2 which should transfer OK to the mega, but the hardware output pins are different.

// Inline functions (this saves precious cycles in the ISR)
#if AUDIO_PIN == 3
#  define OCR2 OCR2B
#endif
#if AUDIO_PIN == 11
#  define OCR2 OCR2A
#endif

On the Mega OCR2A =digital 10 and OCR2B = digital 9

A lot of thanks cattledog.

I tried this, but I can't read anything at Arduino MEGA 10 digital pin.

avr_afsk.h

/*
#if AUDIO_PIN == 3
#  define OCR2 OCR2B
#endif
*/
#if AUDIO_PIN == 10
#  define OCR2 OCR2A
#endif

avr_afsk.cpp

void afsk_timer_setup()
{
  // Set up Timer 2 to do pulse width modulation on the speaker
  // pin.
  
  // Source timer2 from clkIO (datasheet p.164)
  ASSR &= ~(_BV(EXCLK) | _BV(AS2));
  
  // Set fast PWM mode with TOP = 0xff: WGM22:0 = 3  (p.150)
  // This allows 256 cycles per sample and gives 16M/256 = 62.5 KHz PWM rate
  
  TCCR2A |= _BV(WGM21) | _BV(WGM20);
  TCCR2B &= ~_BV(WGM22);
  
  // Phase correct PWM with top = 0xff: WGM22:0 = 1 (p.152 and p.160))
  // This allows 510 cycles per sample and gives 16M/510 = ~31.4 KHz PWM rate
  //TCCR2A = (TCCR2A | _BV(WGM20)) & ~_BV(WGM21);
  //TCCR2B &= ~_BV(WGM22);

/*  
#if AUDIO_PIN == 11
  // Do non-inverting PWM on pin OC2A (arduino pin 11) (p.159)
  // OC2B (arduino pin 3) stays in normal port operation:
  // COM2A1=1, COM2A0=0, COM2B1=0, COM2B0=0
  TCCR2A = (TCCR2A | _BV(COM2A1)) & ~(_BV(COM2A0) | _BV(COM2B1) | _BV(COM2B0));
#endif  
*/

#if AUDIO_PIN == 10
  // Do non-inverting PWM on pin OC2B (arduino pin 3) (p.159).
  // OC2A (arduino pin 11) stays in normal port operation: 
  // COM2B1=1, COM2B0=0, COM2A1=0, COM2A0=0
  TCCR2A = (TCCR2A | _BV(COM2B1)) & ~(_BV(COM2B0) | _BV(COM2A1) | _BV(COM2A0));
#endif
  
  // No prescaler (p.162)
  TCCR2B = (TCCR2B & ~(_BV(CS22) | _BV(CS21))) | _BV(CS20);

  // Set initial pulse width to the rest position (0v after DC decoupling)
  OCR2 = REST_DUTY;
}

void afsk_timer_start()
{
  // Clear the overflow flag, so that the interrupt doesn't go off
  // immediately and overrun the next one (p.163).
  TIFR2 |= _BV(TOV2);       // Yeah, writing a 1 clears the flag.

  // Enable interrupt when TCNT2 reaches TOP (0xFF) (p.151, 163)
  TIMSK2 |= _BV(TOIE2);
}

void afsk_timer_stop()
{
  // Output 0v (after DC coupling)
  OCR2 = REST_DUTY;

  // Disable playback interrupt
  TIMSK2 &= ~_BV(TOIE2);
}

Is AUDIO_PIN defined in a config file somewhere, or is it in your code?

cattledog:
Is AUDIO_PIN defined in a config file somewhere, or is it in your code?

Yes, is defined in config.h file:

With Arduino UNO (that works fine):

// AUDIO_PIN is the audio-out pin. The audio is generated by timer 2 using
// PWM, so the only two options are pins 3 and 11.
// Pin 11 doubles as MOSI, so I suggest using pin 3 for PWM and leave 11 free
// in case you ever want to interface with an SPI device.
#define AUDIO_PIN       3

With Arduino MEGA 2560 (that doesn't work):

// AUDIO_PIN is the audio-out pin. The audio is generated by timer 2 using
// PWM, so the only two options are pins 3 and 11.
// Pin 11 doubles as MOSI, so I suggest using pin 3 for PWM and leave 11 free
// in case you ever want to interface with an SPI device.
#define AUDIO_PIN       10

Also config.h is included in afsk_avr.cpp file:

#include <avr/io.h>
#include <avr/pgmspace.h>
#include "config.h"
#include "afsk_avr.h"

I also asked in AVR Freaks http://www.avrfreaks.net/comment/2089306#comment-2089306

With Arduino MEGA 2560 (that doesn't work):

// AUDIO_PIN is the audio-out pin. The audio is generated by timer 2 using

// PWM, so the only two options are pins 3 and 11.

On a Mega, Timer2 connects to pins 9 and 10, not 3 and 11

...R

Hello Xload,
I'm trying to use a trackuino 1.52 firmware with Arduino mega2560 too. Could you share me the solution for the problem? In addition, eI'm working with the GPS NEO-7M-C.

Best regards and thanks in advance.

Hello SimpleSpace,

We wrote a library and now is working fine with arduino uno and mega but please note that is just a beta version.

We are working on optimize code and integrate some functions at library and then release it.

Best regards

aprslib.zip (23.1 KB)

We wrote a library and now is working fine with arduino uno and mega

What were the issues in porting for the mega? The simple output pin changes addressed in this thread did not appear to solve the problem.

It works fine at mega digital pin 9 and some minor changes.

Hey guys. I can see that this thread is more than a year old now, but I wanted you to know that I managed to port my Trackuino from an Arduino Uno to an Arduino Mega. It took me a long time to figure out the hardware and software changes that needed to be made, some of it I acquired from this thread. I put together a tutorial and posted it here: http://www.intelleggtual.com/porting-the-trackuino-from-an-arduino-uno-to-arduino-mega/

Hope it helps, and let me know if you end up getting it to work or have questions.