port code from attiny44a to nano

:slight_smile: hello friends of the community, as the title says I would like to "port a code that is designed to work in the micro attiny44a so that it works in a NANO I leave the code to see how you can help me thanks

main.txt (2.89 KB)

this is the circuit :slight_smile:

Please post your code directly to the forum when possible, using code tags (</> button on the toolbar). This will make it easier for people to look at it and so make it more likely for you to get help. If the code exceeds the maximum 9000 characters allowed by the forum then it's OK to use an attachment but in this case it's much less than 9000.

OP's picture (heh. Easier to post than to download and look at!)

The code is not written for the Arduino IDE, so you need to decide whether your "port" will be to an Arduino-like "look", or whether you just want to get it running on the Nano without making it arduino-like (which is probably easier...)

thanks for the answer, what I'm looking for is that it run on the nano, but the closest thing to the original code. the outputs can be pin 3,5,6,7,13 and the inputs 8,12

this is the code sorry :slight_smile:

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

// OUTPUT
#define IGNITION1 PINB0
#define IGNITION2 PINB1
#define IGNITION3 PINB2
#define IGNITION4 PINA7
#define LED       PINA3
#define TACHO     PINA1

// INPUT
#define CYP1      PINA0
#define IGN       PINA2

//VARS
uint8_t CYLINDER    = 0;
uint8_t SPARKS      = 0;
uint16_t RPM        = 0;
uint8_t LEDSTATUS   = 0;

#define WATCHDOG_DELAY WDTO_30MS   // Set watchdog for 30 mSec

void Led_ON(){
        PORTA |= _BV(LED); // LED ON
}

void Led_OFF(){
        PORTA &= ~_BV(LED); // LED OFF
}

// TIMER
ISR(TIM1_COMPA_vect) {
        if (LEDSTATUS == 0) { // Change LED on 2/10 sec
                Led_OFF();
                LEDSTATUS = 1;
        } else {
                Led_ON();
                LEDSTATUS = 0;
        }
        RPM=SPARKS*60*10/8;
        SPARKS=0;
}

void Ignite_ON() {
        switch (CYLINDER) { // Set fire for required coil 1-3-4-2
        case 0: break; // SKIP fire until first CYP signal
        case 1: PORTB |= _BV(IGNITION1); break;
        case 2: PORTB |= _BV(IGNITION3); break;
        case 3: PORTA |= _BV(IGNITION4); break;
        case 4: PORTB |= _BV(IGNITION2); break;
        }
}

void Ignite_Off() {
        PORTB = 0; // Off IGNITION1/2/3
        PORTA &= ~_BV(IGNITION4); // OFF IGNITION4
}

// PCINT0 Vector handling PINS: PCINT0 and PCINT2
ISR(PCINT0_vect) {
        cli();
// Check CYP
        if ( (PINA & _BV(CYP1))==0) { // CYP - LOW
                CYLINDER=1;
        }
// Check IGN
        if ( ((PINA & _BV(IGN))==0) && (CYLINDER > 0)) { // Start FIRE - LOW after first CYP1
                PORTA |= _BV(TACHO); // ON TACH
                Ignite_ON();
                SPARKS++;
                while ((PINA & _BV(IGN))==0) ;
                Ignite_Off();
                PORTA &= ~_BV(TACHO); // OFF TACH
                CYLINDER++;
                if (CYLINDER > 4) { // if we lost CYP1 signal
                        CYLINDER = 1;
                }
        }
        sei();
}

int main(void) {
        cli();
        CYLINDER = 0; // Make shure for wait CYP1
// Setup
        DDRB = _BV(IGNITION1) | _BV(IGNITION2) | _BV(IGNITION3);
        DDRA = _BV(TACHO) | _BV(LED) | _BV(IGNITION4);
        GIMSK = _BV(PCIE0);
        MCUCR |= _BV(ISC00); //ISC00 - any change
        PCMSK0 = _BV(PCINT0) | _BV(PCINT2);

//Timer1 is used as 1/10 sec time base
//Timer Clock = 1/1024 of sys clock
//Mode = CTC (Clear Timer On Compare)
        TCCR1B |= ((1<<WGM12)|(1<<CS12)|(1<<CS10));
        OCR1A = 8000000/1024/10;  //Compare value
        TIMSK1 |= (1<<OCIE1A);    //Output compare 1A interrupt enable

        wdt_enable (WATCHDOG_DELAY); // Enable WATCHDOG
        sei();

// Main loop
        while ( 1 ) {
                wdt_reset (); // reset WDR
                _delay_us(1);
        }
}

up?

Some basic translations:

DDRx |= _BV(PinName);
means
pinMode(PinName, OUTPUT);
PORTx |= _BV(PinName);
means
digitalWrite(PinName, HIGH);
PORTx &= ~_BV(IGNITION4);
means
digitalWrite(PinName, LOW);
if (PINx & _BV(PinName)) {
means
if (digitalRead(PinName))

so change it, please check to see if it's ok thanks

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

#define DDRB _SFR_IO8(0x17)
#define DDRA _SFR_IO8(0x1A)
#define MCUCR _SFR_IO8(0x35)
#define GIMSK _SFR_IO8(0x3B)
#define PCMSK0 _SFR_IO8(0x12)

// INPUT- OUTPUTS //
int COIL1    = 3;
int COIL2    = 5;
int COIL3    = 6;
int COIL4    = 7;
int LED      = 13;
int COILTR   = 8;
int SYNCTR   = 12;
int TACH     = 2;

//VARS
uint8_t CYLINDER    = 0;
uint8_t SPARKS      = 0;
uint16_t RPM        = 0;
uint8_t LEDSTATUS   = 0;

#define WATCHDOG_DELAY WDTO_30MS   // Set watchdog for 30 mSec

void Led_ON() {
  digitalWrite(3, HIGH); // LED ON
}

void Led_OFF() {
  digitalWrite(3, LOW); // LED OFF
}

// TIMER
ISR(TIM1_COMPA_vect) {
  if (LEDSTATUS == 0) { // Change LED on 2/10 sec
    Led_OFF();
    LEDSTATUS = 1;
  } else {
    Led_ON();
    LEDSTATUS = 0;
  }
  RPM = SPARKS * 60 * 10 / 8;
  SPARKS = 0;
}

void Ignite_ON() {
  switch (CYLINDER) { // Set fire for required coil 1-3-4-2
    case 0: break; // SKIP fire until first CYP signal
    case 1: PORTB |= _BV(3); break;
    case 2: PORTB |= _BV(6); break;
    case 3: digitalWrite(7, HIGH); break;
    case 4: PORTB |= _BV(5); break;
  }
}

void Ignite_Off() {
  PORTB = 0; // Off IGNITION1/2/3
  digitalWrite (7, LOW); // OFF IGNITION4
}

// PCINT0 Vector handling PINS: PCINT0 and PCINT2
ISR(PCINT0_vect) {
  cli();
  // Check CYP
  if ( (8 & _BV(12)) == 0) { // CYP - LOW
    CYLINDER = 1;
  }
  // Check IGN
  if ( ((8 & _BV(12)) == 0) && (CYLINDER > 0)) { // Start FIRE - LOW after first CYP1
    digitalWrite(2, HIGH); // ON TACH
    Ignite_ON();
    SPARKS++;
    while ((8 & _BV(12)) == 0) ;
    Ignite_Off();
    digitalWrite(2, LOW); // OFF TACH
    CYLINDER++;
    if (CYLINDER > 4) { // if we lost CYP1 signal
      CYLINDER = 1;
    }
  }
  sei();
}

int main(void) {
  cli();
  CYLINDER = 0; // Make shure for wait CYP1
  // Setup
  DDRB = _BV(3) | _BV(5) | _BV(6);
  DDRA = _BV(2) | _BV(13) | _BV(7);
  MCUCR |= _BV(ISC00); //ISC00 - any change
  PCMSK0 = _BV(PCINT0) | _BV(PCINT2);

  //Timer1 is used as 1/10 sec time base
  //Timer Clock = 1/1024 of sys clock
  //Mode = CTC (Clear Timer On Compare)
  TCCR1B |= ((1 << WGM12) | (1 << CS12) | (1 << CS10));
  OCR1A = 8000000 / 1024 / 10; //Compare value
  TIMSK1 |= (1 << OCIE1A);  //Output compare 1A interrupt enable

  wdt_enable (WATCHDOG_DELAY); // Enable WATCHDOG
  sei();

  // Main loop
  while ( 1 ) {
    wdt_reset (); // reset WDR
    _delay_us(1);
  }
}
#define DDRB _SFR_IO8(0x17)

#define DDRA _SFR_IO8(0x1A)
#define MCUCR _SFR_IO8(0x35)
#define GIMSK _SFR_IO8(0x3B)
#define PCMSK0 _SFR_IO8(0x12)

Don't do that. Those symbols are already defined in io.h. If you have an Arduino sketch, io.h is already included.

    case 1: PORTB |= _BV(3); break;

case 2: PORTB |= _BV(6); break;

Don't do that either; in the original the pins had nice symbolic names, and there is no reason to use "mysterious" non-symbolic constants in the modified version.

int LED      = 13;
   :
void Led_ON() {
  digitalWrite(3, HIGH); // LED ON
}

Why?

Here is a full translation. It would have been easier if the pin names used in the code were the same as the pin names used in the schematic.

#include <avr/wdt.h>
#define WATCHDOG_DELAY WDTO_30MS   // Set watchdog for 30 mSec


// OUTPUTS //
const byte IGN1    = 3;  // Was PB0
const byte IGN2    = 5;  // Was PB1
const byte IGN3    = 6;  // Was PB2
const byte IGN4    = 7;  // Was PA7
const byte LED      = 13;  // Was PA3
const byte TACHO     = 2;  // Was PA1
// INPUTS //
const byte SYNCTR   = 12;  // CYP1? PA0?
const byte COILTR   = 8;  // IGN? PA2?


//VARS
uint8_t CYLINDER    = 0;
uint8_t SPARKS      = 0;
uint16_t RPM        = 0;
uint8_t LEDSTATUS   = 0;


// TIMER INTERRUPT
ISR(TIMER1_COMPA_vect)
{
  LEDSTATUS = !LEDSTATUS;
  digitalWrite(LED, LEDSTATUS);
  
  RPM = SPARKS * 60 * 10 / 8;
  SPARKS = 0;
}


void Ignite_ON()
{
  switch (CYLINDER)   // Set fire for required coil 1-3-4-2
  {
    case 0: break; // SKIP fire until first CYP signal
    case 1: digitalWrite(IGN1, HIGH); break;
    case 2: digitalWrite(IGN3, HIGH); break;
    case 3: digitalWrite(IGN4, HIGH); break;
    case 4: digitalWrite(IGN2, HIGH); break;
  }
}


void Ignite_Off()
{
  digitalWrite(IGN1, LOW);
  digitalWrite(IGN3, LOW);
  digitalWrite(IGN4, LOW);
  digitalWrite(IGN2, LOW);
}


// PIN CHANGE INTERRUPT 0  Vector handling PINS: PCINT0 and PCINT2
ISR(PCINT0_vect)
{
  // Check CYP
  if (digitalRead(SYNCTR) == LOW)   // CYP - LOW
  {
    CYLINDER = 1;
  }
  
  // Check IGN
  if ((digitalRead(COILTR) == LOW) && (CYLINDER > 0))   // Start FIRE - LOW after first CYP1
  {
    digitalWrite(TACHO, HIGH); // ON TACH
    Ignite_ON();
    SPARKS++;
    while (digitalRead(COILTR) == LOW) ;
    Ignite_Off();
    digitalWrite(TACHO, LOW); // OFF TACH
    CYLINDER++;
    if (CYLINDER > 4)   // if we lost CYP1 signal
    {
      CYLINDER = 1;
    }
  }
}


void setup()
{
  CYLINDER = 0; // Make shure for wait CYP1
  
  // Setup
  pinMode(IGN1, OUTPUT);
  pinMode(IGN2, OUTPUT);
  pinMode(IGN3, OUTPUT);
  pinMode(IGN4, OUTPUT);
  pinMode(LED, OUTPUT);
  pinMode(TACHO, OUTPUT);


  pinMode(SYNCTR, INPUT);
  pinMode(COILTR, INPUT);


// Enable Pin Change Interrupt on SYNCTR and COILTR
  // MCUCR |= _BV(ISC00); //ISC00 - any change
  // PCMSK0 = _BV(PCINT0) | _BV(PCINT2);


  //Timer1 is used as 1/10 sec time base
  //Timer Clock = 1/1024 of sys clock
  //Mode = CTC (Clear Timer On Compare)
  TCCR1B |= ((1 << WGM12) | (1 << CS12) | (1 << CS10));
  OCR1A = 8000000 / 1024 / 10; //Compare value
  TIMSK1 |= (1 << OCIE1A);  //Output compare 1A interrupt enable


  wdt_enable (WATCHDOG_DELAY); // Enable WATCHDOG
}


// Main loop
void loop()
{
  wdt_reset (); // reset Watchdog Timer
}