Home › Forums › Arduino Board › Atmel to Arduino program › Reply To: Atmel to Arduino program
October 1, 2016 at 10:18 pm
#13047
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;
}
}
}
