Reply To: Atmel to Arduino program

Home Forums Arduino Board Atmel to Arduino program Reply To: Atmel to Arduino program

#13047

heat_z0ne
Participant

I am using Arduino 1.6.10 , i think its latest version.

I have Atmel 8MHz code for cable tester and pin used are ADC0( PA0) to ADC7(PA7) as analog pin and PC0 to PC7 as digital pin.

If i want to use same program for Arduino mega 16Mhz with A8 to A15 analog pin and 42 to 49 ad Digital Pin.

My question is what i have to change to get it work on Arduino Mega.

Here is code:

#include <avr/io.h>
#include <util/delay.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <math.h>
#include <avr/pgmspace.h>

#include "hd44780.h" // LCD
#include "lan_tester.h"

#define F_CPU 16000000UL //8

//----------------------------------------------------------------
float GetADCData (uchar nChannel)
{
  ADCSRA = 0;
  _delay_us (5);
  ADMUX = 0b01000000 | (nChannel & 0b00000111); // 64, 7
  _delay_us (5);
  ADCSRA = 0b10000101;//5
  _delay_us (500);
  ADCSRA = 0b11000101; // 69
  while ((ADCSRA & (1 << 6)));
  _delay_us (5);
  int nResult = ((int) ADCL) + (((int) ADCH) << 8);
  return (float) nResult;
}

//----------------------------------------------------------------
void SetTestLines (uchar nPositive, uchar nNegative, bool bWait)
{
  DDRC = 0;
  PORTC = 0;
  if (nPositive != LINE_UNUSED)
  {
    DDRC |= (1 << nPositive);
    PORTC |= (1 << nPositive);
  }

  if (nNegative != LINE_UNUSED)
  {
    DDRC |= (1 << nNegative); 
  }
  if (bWait) _delay_ms (20);
    return;
}

//----------------------------------------------------------------
void ShowFault (uchar nCode)
{
  lcdClear ();
  static char strMessage11 [] PROGMEM = "    On line    ";
  static char strMessage12 [] PROGMEM = "There is tension!";
  static char strMessage21 [] PROGMEM = "Replace the battery";
  static char strMessage31 [] PROGMEM = " ADC faulty ";

  switch (nCode)
  {
    case 0:
      lcdGotoXY (1, 0);
      lcdPutsFromFlash (strMessage11);
      lcdGotoXY (2, 0);
      lcdPutsFromFlash (strMessage12);
      break;
  case 1: 
    lcdGotoXY (1, 0);
    lcdPutsFromFlash (strMessage21);
    break;
  case 2:
    lcdGotoXY (1, 0);
    lcdPutsFromFlash (strMessage31);
    break;
  }
  return;
}

//----------------------------------------------------------------
bool CheckLineVoltage (float *Umin, float *Umax)
{
  bool bFlag = false;

  SetTestLines (LINE_UNUSED, LINE_UNUSED, true);
  for (int i = 0; i < 8; i++)
  {
    if (GetADCData (i) > fZero) bFlag = true;
  }

  if (bFlag)
  {
    ShowFault (0);
    return false;
  }

  if (!PINB2)
  {
    ShowFault (1);
    return false;
  }

  SetTestLines (LINE_UNUSED, 0, true);
  *Umin = GetADCData (0);

  SetTestLines (0, LINE_UNUSED, true);
  *Umax = GetADCData (0);
  if ((*Umax - *Umin) < 700)
  {
    ShowFault (2); 
    return false;
  }

  return true;
}

//----------------------------------------------------------------
bool CheckConnection (char *Data, char *Mask)
{
  for (uchar i = 0; i < 8; i++)
  {
    if ((Data [i] != Mask [i]) && (Mask [i] != 'X')) return false;
  }
  return true;
}

//----------------------------------------------------------------
void RefreshDisplay (uchar *Data, int L, bool bShowLength)
{
  char str [9];

  static char strMessage0 [] PROGMEM = "Main:  12345678";
  static char strMessage1 [] PROGMEM = "1Gb LAN Staight ";
  static char strMessage2 [] PROGMEM = "1Gb LAN Cross   ";
  static char strMessage3 [] PROGMEM = "100Mb LAN Straight";
  static char strMessage4 [] PROGMEM = "100Mb LAN Cross ";
  static char strMessage5 [] PROGMEM = "E1/T1           ";
  static char strMessage6 [] PROGMEM = "No connection   ";
  static char strMessage7 [] PROGMEM = "                ";

  lcdGotoXY (0, 0);
  lcdPutsFromFlash (strMessage0);
  lcdGotoXY (1, 0);
  lcdPutsFromRAM ("Remote:    ");
  for (int i = 0; i < 8; i++)
  {
    switch (Data [i])
    {
      case 1:
      case 2:
      case 3:
      case 4:
      case 5:
      case 6:
      case 7:
      case 8:       
        str [i] = Data [i] + 48; 
        break;
      case LINE_UNKNOWN:  
        str [i] = '?'; 
        break;
      case LINE_SHORTED:  
        str [i] = 'S'; 
        break;
      case LINE_BROKEN: 
        str [i] = 'X';  
        break;

      default: 
        str [i] = ' ';
    } 
  }
  str [8] = 0;
  lcdPutsFromRAM (str);
  lcdPutsFromRAM ("    ");

  lcdGotoXY (2, 0);
  if (bShowLength)
  {
    if (L < 5) 
    {
      lcdPutsFromRAM ("Cable Length <5 м  ");
    }
    else
    {
      lcdPutsFromRAM ("Cable Length ");
      itoa (L, str, 10);
      lcdPutsFromRAM (str);
      lcdPutsFromRAM (" M  ");
    }
  }
  else
  {
    lcdPutsFromFlash (strMessage7); 
  }

  lcdGotoXY (3, 0);
  if (CheckConnection (str, "12345678"))    
    lcdPutsFromFlash (strMessage1);
  else if (CheckConnection (str, "36145278")) 
    lcdPutsFromFlash (strMessage2);
  else if (CheckConnection (str, "123XX6XX")) 
    lcdPutsFromFlash (strMessage3);
  else if (CheckConnection (str, "361XX2XX")) 
    lcdPutsFromFlash (strMessage4);
  else if (CheckConnection (str, "45X12XXX")) 
    lcdPutsFromFlash (strMessage5);
  else 
    lcdPutsFromFlash (strMessage6);

  return;
}

//----------------------------------------------------------------
void Initialize ()
{
  DDRA = 0;
  DDRB = 0;
  DDRC = 0;
  DDRD = 0;
  PORTA = 0;
  PORTB = 0;
  PORTC = 0;
  PORTD = 0;
  MCUCSR = 0b10000000;
  TCCR1A = 0;
  TCCR1B = 0;

  _delay_ms (100);
  lcdInit();

  return;
}

//----------------------------------------------------------------
float GetResistance (uchar Line1, uchar Line2, float Umin)
{
  SetTestLines (Line1, Line2, true);
  float U1 = GetADCData (Line1);
  float U2 = GetADCData (Line2);
  float Ra = R1 * R2 / (R1 + R2);
  if ((U2 - Umin) <= 0) 
    return 1e6;
  return (U1 - U2) * Ra / (U2 - Umin);
}

//----------------------------------------------------------------
uchar StageOneCheck (uchar *Line, const uchar *PinOut, uchar *GoodLine, uchar *BrokenIndex)
{
  uchar LineCount = 0;
  *BrokenIndex = LINE_UNUSED;
  for (uchar i = 0; i < 8; i++) 
  {
    Line [i] = 0;
    SetTestLines (PinOut [i], LINE_UNUSED, true);
    bool bFlag = false;
    for (uchar j = 0; j < 8; j++) 
    {
      float fADCData = GetADCData (PinOut [j]);
      if ((fADCData > fMaxValue) && (i != j)) 
        Line [i] = LINE_SHORTED;
      if ((fADCData > fZero) && (i != j)) 
         bFlag = true;
    }
    if (!bFlag) 
    {
      Line [i] = LINE_BROKEN;
      *BrokenIndex = i;
    }
    if (Line [i] == 0) 
      GoodLine [LineCount++] = i;
  }

  return LineCount;
}

//----------------------------------------------------------------
void StageTwoCheck (uchar *Line, const uchar *PinOut, uchar *GoodLine, uchar LineCount, const float R [3][8], float Umin)
{
  volatile static float fRcalc [8];
  uchar i = 0, j = 0;
  uchar nMinIndex [3] = {0, 0, 0};
  float fMinResistance = 1e6;
  float Rtmp;

  // find two lines with minimal resistance
  for (i = 1; i < LineCount; i++) 
  {
    for (j = 0; j < i; j++)
    {
      Rtmp = GetResistance (PinOut [GoodLine [i]], PinOut [GoodLine [j]], Umin);
      if (Rtmp < fMinResistance)
      {
        fMinResistance = Rtmp;
        nMinIndex [0] = i; 
        nMinIndex [1] = j;
      }
    }
  }

  // find third line
  fMinResistance = 1e6;
  for (i = 0; i < LineCount; i++)
  {
    if ((i != nMinIndex [0]) && (i != nMinIndex [1]))
    {
      Rtmp = GetResistance (PinOut [GoodLine [nMinIndex [0]]], PinOut [GoodLine [i]], Umin);
      if (Rtmp < fMinResistance)
      {
        fMinResistance = Rtmp;
        nMinIndex [2] = i;
      }
    }
  }

  // solve equations
  float fR12 = GetResistance (PinOut [GoodLine [nMinIndex [0]]], PinOut [GoodLine [nMinIndex [1]]], Umin);
  float fR13 = GetResistance (PinOut [GoodLine [nMinIndex [0]]], PinOut [GoodLine [nMinIndex [2]]], Umin);
  float fR23 = GetResistance (PinOut [GoodLine [nMinIndex [1]]], PinOut [GoodLine [nMinIndex [2]]], Umin);
  float fR1 = 0.5 * (fR12 + fR13 - fR23);
  float fR2 = fR12 - fR1;
  uchar idxMin;

  if (fR1 < fR2)
  {
    idxMin = nMinIndex [0];
    fRcalc [idxMin] = fR1; 
  }
  else
  {
    idxMin = nMinIndex [1];
    fRcalc [idxMin] = fR2;
  }

  for (i = 0; i < LineCount; i++)
  {
    if (i != idxMin) 
    {
      Rtmp = GetResistance (PinOut [GoodLine [i]], PinOut [GoodLine [idxMin]], Umin);
      fRcalc [i] = Rtmp - fRcalc [idxMin];
    }
  }

  // try to found according resistance in table
  for (i = 0; i <= LineCount; i++)
  {
    for (j = 0; j < 8; j++)
    {
      if ((R [1][j] < fRcalc [i]) && (fRcalc [i] < R [2][j]))
      {
        Line [GoodLine [i]] = j + 1;
        break;
      }
    }
    if (Line [GoodLine [i]] == 0) Line [GoodLine [i]] = LINE_UNKNOWN;
  }

  return;
}

//----------------------------------------------------------------
int StageThreeCheck (uchar BrokenIndex, const uchar *PinOut)
{
  SetTestLines (PinOut [BrokenIndex], LINE_UNUSED, true);
  float U1 = GetADCData (PinOut [BrokenIndex]);
  TCNT1H = 0;
  TCNT1L = 0;
  TCCR1B = 1;
  SetTestLines (LINE_UNUSED, LINE_UNUSED, false);
  _delay_ms (1);
  float U2 = GetADCData (PinOut [BrokenIndex]);
  TCCR1B = 0;
  int nTime = ((int) TCNT1L) + (((int) TCNT1H) << 8);
  float fTime = ((float) nTime) * 1000 / F_CPU;
  float L = (-fTime/log (U2 / U1) - 1.71) / 0.032;
  return (int) L;
}

//----------------------------------------------------------------
void EasterEgg ()
{
  static int i = 0;
  static char strMessage1 [] PROGMEM = "                ";
  static char strMessage2 [] PROGMEM = "LAN-Tester v 1.1";
  static char strMessage3 [] PROGMEM = "          ";
  static char strMessage4 [] PROGMEM = "                ";

  if (++i == 120)
  {
    lcdClear ();
    lcdGotoXY (0, 0);
    lcdPutsFromFlash (strMessage1);
    lcdGotoXY (1, 0);
    lcdPutsFromFlash (strMessage2);
    lcdGotoXY (2, 0);
    lcdPutsFromFlash (strMessage3);
    lcdGotoXY (3, 0);
    lcdPutsFromFlash (strMessage4);
    _delay_ms (5000);
    lcdClear ();
  }
  return;
}

//----------------------------------------------------------------
int main()
{
  const uchar PinOut [8] = {6, 5, 7, 4, 0, 3, 1, 2};
  const float R [3][8] = {{15, 8.2, 51, 3.0, 5.1, 2.0, 22, 1.0},
                          {13, 7.5, 40, 2.5, 4.0, 1.5, 18, 0.7},
                          {18, 9.5, 60, 3.8, 6.5, 2.5, 27, 1.5}};
  float Umax, Umin;
  int L = 0;
  uchar Line [8];
  uchar GoodLine [8];
  uchar BrokenIndex;
  uchar Step = 0;
  uchar LineCount = 0;
  uchar i;
 
  Initialize ();

  while (1)
  {
    switch (Step)
    {
      case 0:       // startup checks
        if (CheckLineVoltage (&Umin, &Umax)) Step = 1;
        break;
      case 1:       // try to found unbroken line, check for shortage
        LineCount = StageOneCheck (Line, PinOut, GoodLine, &BrokenIndex);
        if (LineCount < 3)
        {
          for (i = 0; i < 8; i++)
          {
            if (Line [i] == 0) 
              Line [i] = LINE_UNKNOWN;
          }
          Step = 3; 
        }
        else
        {
          Step = 2;
        }
        break;

        case 2:     // resistance measure, lines order check
          StageTwoCheck (Line, PinOut, GoodLine, LineCount, R, Umin);
          if (BrokenIndex == LINE_UNUSED) 
            Step = 4; 
          else 
            Step = 3;
          break;
        case 3:     // capacitance measure, if there are broken lines
          L = StageThreeCheck (BrokenIndex, PinOut);
          Step = 4;
          break;

        case 4:   // display refresh
          RefreshDisplay (Line, L, (BrokenIndex != LINE_UNUSED));
          EasterEgg ();

        default:
          Step = 0;
    }
  }
}
string(7) "9898001"