Convert code for Adafruit Trinket to run on Arduino Uno/Nano

Hi All,

Im trying to help someone out who is having a bit of bother. The code below is for a continuity tester/fault finder, and was written for a 3v 12MHz Adafruit Trinket Pro. Project details, schematic etc here Shorty - short circuit finder | Hackaday.io

I have been asked to see if it will work on an Uno or Nano. It compiles ok but im not in a position at present to actually upload it to a board (too late at night and the Arduinos are in my sons room!)

I have a few reservations though. The code seems to be written as a mish mash of C++ and assembler! There looks to me to be clock frequency settings that I think will need changing. It also looks like it has a form of serial debugging, but i cant work out if this would actually send data back over the USB to the serial monitor?

Apologies for the poor copy and paste of the code, for some reason the 'copy for forum' and 'paste code' dont seem to be working right for me!

All I need to do is get it to work on an uno or nano and provide an artificial input to the analogue pin, to see if it functions as expected

I would very much appreciate any help and pointers

#include <avr/io.h>
#include <util/delay.h>

#ifndef F_CPU
#define F_CPU 12000000UL
#endif
#define _BAUD  9600  // Baud rate (9600 is default)
#define _UBRR (F_CPU/16)/_BAUD - 1  // Used for UBRRL and UBRRH 


#define  BUZZER_PORT PORTD
#define  BUZZER_DDR DDRD
#define  BUZZER 6

#define LED_TIMER_ON  500
#define LED_TIMER_MAX  550

unsigned int adc_val;
#define AVERAGE_SIZE 5
unsigned int adc_val_avg[AVERAGE_SIZE],adc_val_acc;
unsigned char adc_val_avg_ptr,i,probe_state;
unsigned int led_timer,led_;
unsigned int probe_timer;

int main (void)
{
  UBRR0H = ((_UBRR) & 0xF00);
  UBRR0L = (uint8_t) ((_UBRR) & 0xFF); 
  UCSR0B |= _BV(TXEN0);
  UCSR0B |= _BV(RXEN0);
  
    DDRD |= (1 << DDD6);
    DDRD &= ~(1 << DDD3);
    PORTD |= (1 << PORTD3);
    DDRC |= (1 << DDC3);
    DDRB |= (1 << DDC5);
    PORTC &= ~(1 << PORTC3);
    OCR0A = 120;
    TCCR0A = 0x42;
    TCCR0B = 0x05;
  ADCSRA = (1<<ADEN) | (1<<ADPS2) | (1<<ADPS0);
  ADMUX=0x45;
//  ADMUX |= (1 << ADLAR); // Left adjust ADC result to allow easy 8 bit reading
probe_timer = 0;
led_timer = 0;
probe_state=1;
while (1)
{
  //if probe is active, blink a LED
  led_timer++;
  if ((led_timer>LED_TIMER_ON)&(probe_state==1))
    PORTB |= (1<<5);
  else
    PORTB &= ~(1<<5);
  if (led_timer>LED_TIMER_MAX)
    led_timer = 0;
  
  //now decide, if the probe wasn't inactive for too long  
  probe_timer++;
  if (probe_timer>15000)
    {
    if (probe_state==1)
      probe_state=0;
    }
  
  //inactive probe code
  if (probe_state==0)
    {
    PORTC |= (1 << PORTC3);
    DDRD &= ~(1 << DDD6);
    _delay_ms(1);
    if ((PIND&(0x08))==0)
      {
      probe_state=1;
      probe_timer = 0;
      }
    }

  //active probe code  
  if (probe_state==1)
  {
  PORTC &= ~(1 << PORTC3);
  _delay_ms(1);
  //take adc sample
  ADCSRA |= (1<<ADSC);          // Start conversion
  while (ADCSRA & (1<<ADSC));   // wait for conversion to complete
  adc_val = ADCW;
  
  //take value and put it into floating average
  adc_val_avg[adc_val_avg_ptr++] = adc_val;
  if (adc_val_avg_ptr>AVERAGE_SIZE) adc_val_avg_ptr = 0;
  adc_val_acc = 0;
  for (i=0;i<AVERAGE_SIZE;i++)
    adc_val_acc = adc_val_acc + adc_val_avg[i];
  adc_val_acc = adc_val_acc / 20;
  adc_val = adc_val_acc;

  //decide what to do
  if (adc_val>200) adc_val = 200;
  adc_val = adc_val + 2;
  if (adc_val<200)
    {
    OCR0A = adc_val;
    DDRD |= (1 << DDD6);
    probe_timer = 0;
    }
  else
    {
    DDRD &= ~(1 << DDD6);
    }
  }
  
  
  }
  
}

void usart_tx_b(uint8_t data)
{
while (!(UCSR0A & _BV(UDRE0)));
UDR0 = data;
}
void usart_tx_hexa (uint8_t value)
{
uint8_t temp;
temp = value;
usart_tx_b('0');
usart_tx_b('x');
temp = ((temp>>4)&0x0F);
if (temp<10) temp = temp + '0';
else temp = temp + 'A'- 10;
usart_tx_b(temp);
temp = value;
temp = ((temp>>0)&0x0F);
if (temp<10) temp = temp + '0';
else temp = temp + 'A' - 10;
usart_tx_b(temp);
usart_tx_b(' ');
}

Several things: First, it is not a C program in the sense that it requires main() to execute. The Arduino IDE buries the call to main() in its own setup code. Second, the code really is not doing assembler, but it is doing a lot of bit flipping and working directly with the Arduino ports. I don't know anything about the Trinket Pro, but believe that it is AT328 compatible on the instruction set, but has a slower clock speed and works off of 3.3V. If that's true, you should be able to use the Arduino Nano, although it will draw slightly more power than the Trinket and uses a 5V power source (7-12V works).

My guess is that the code in main() before the while (1) statement would go into the Arduino setup() function. The rest of the code in the while(1) loop (but not the loop itself) would go into the loop() function. The other functions would keep their global scope. If you have a Nano, you might give that a try. Like I said, I know nothing about the Trinket, but, what the heck, Custer took a chance.

That code compiles and uploads fine to a Nano under IDE 1.6.5, starts with LED blinking about twice a second, don't know if it works correctly with hardware (I don't have).

Many thanks chaps. I intend to try it ona board as soon as I can but it might be a couple of days. The external hardware will be simplified just to test.

756, the fact it worked on your board and the led blinked as expected is a very good sign! Did you happen to notice if you were able to get any data back over the serial monitor?

Nothing on serial monitor, course I didn't put anything in. :confused:

Thanks,

well, we seem to have managed to talk the chap through getting the code loaded into the Trinket, and its working after a fashion. The trinket is an odd beast in that it has a custom bootloader and no serial chip - so you can program it via the USB connector but you cant use that to return serial data!

He has verified that the code does what it should using a pot on the input pin, he now just has to tame the external hardware!

You need an FTDI adapter like AdaFruit's "FTDI Friend".