Sari la conținut
ELFORUM - Forumul electronistilor

Migrare Arduino pe ATmega328P ?


messu

Postări Recomandate

Am testat sketch-ul postat de autorul proiectului pe Arduino Duemilanove (ATMega328 DIP 28 pini).

Cam asa arata ADCSRA si ADMUX fara sa intervin asupra setarilor cu exceptia modificarii pinului de intrare analogica pe A3 si a encoderului pe A1 si A2.

:nerv

 Se poate observa din registri ca ADMUX indica intrarea analogica A6, referinta de tensiune este setata pe o valoare rezervata, nu pe 5V, iar ADCSRA ne indica faptul ca este activata intreruperea, convertorul este activat si prescalerul este 128. Tot ce am afirmat aici este gresit.

Si partea de sketch folosita la printare a fost asta:

 

void setup() {
  uint16_t temp = 0;
  GLCD.Init();            
  GLCD.SelectFont(System5x7);
  
  Serial.begin(9600);
  b[0]= 0;

  Wire.begin();
  Serial.begin(9600);
  Serial.flush();  
  Serial.println(F("*Antuino v2.1"));
  analogReference(DEFAULT);
temp = analogRead(DBM_READING);
  unsigned long last_freq = 0;
  EEPROM.get(MASTER_CAL, xtal_freq_calibrated);
  EEPROM.get(LAST_FREQ, last_freq);
  EEPROM.get(OPEN_HF, openHF);
  EEPROM.get(OPEN_VHF, openVHF);
  EEPROM.get(OPEN_UHF, openUHF);
  EEPROM.get(LAST_SPAN, selectedSpan);
  EEPROM.get(LAST_MODE, mode);

adcsra_temp = ADCSRA;
admux_temp = ADMUX;
Serial.print("ADCSRA = ");
Serial.println(adcsra_temp, BIN);
Serial.print("ADMUX = ");
Serial.println(admux_temp, BIN);

  Serial.print("*hf_open:");
  Serial.println(openHF);
  //the openHF reading is actually -19.5 dbm
  dbmOffset = -23 - openHF;

  Serial.println(last_freq);
  if (0 < last_freq && last_freq < 500000000l)
      centerFreq = last_freq;

  if (xtal_freq_calibrated < 26900000l || xtal_freq_calibrated > 27100000l)
    xtal_freq_calibrated = 27000000l;

  if (mode < 0 || mode > 2)
    mode = 0;

  spanFreq = spans[selectedSpan];
  
  pinMode(ENC_A, INPUT_PULLUP);
  pinMode(ENC_B, INPUT_PULLUP);
  pinMode(FBUTTON, INPUT_PULLUP);
 

  if (btnDown()){
    calibration_mode();
  }else{
    updateScreen();
  }
  si5351aOutputOff(SI_CLK0_CONTROL);
  takeReading(frequency);
  updateMeter();
}

int prev = 0;

 

Link spre comentariu
  • Răspunsuri 95
  • Creat
  • Ultimul Răspuns

Top autori în acest subiect

  • messu

    18

  • daniels

    15

  • nico_2010

    15

  • Marin1960

    11

Top autori în acest subiect

Imagini postate

Am testat si eu sketch-ul respectiv cu modificarile sugerate de @messu si @nico_2010,

...
#define ENC_A (A2)  //A3
#define ENC_B (A1)
#define FBUTTON (0) //A2
...
#define DBM_READING (A3)    //A6
...
void setup() {
...
  analogReference(DEFAULT);
  
  int adc = analogRead(DBM_READING);
  
...  
  
  byte adcsra_temp = ADCSRA;
  byte admux_temp = ADMUX;
  Serial.print("ADCSRA = ");
  Serial.println(adcsra_temp, BIN);
  Serial.print("ADMUX = ");
  Serial.println(admux_temp, BIN);
  Serial.print("ADCs = ");
  Serial.println(adc);
  
  Serial.print("*hf_open:");
  Serial.println(openHF);
  //the openHF reading is actually -19.5 dbm
  dbmOffset = -23 - openHF;

  Serial.println(last_freq);
...
}

pe Arduino Nano si Uno.

Rezultatul este diferit de al lui @nico_2010, dar este conform asteptarilor pe ambele platforme cu atmega 328p:

*Antuino v2.1
ADCSRA = 10010111
ADMUX = 1000011
ADCs = 318
*hf_open:-1
4294967295

ADCSRA are aceiasi valoare ca  pe Arduino Duemilanove, iar ADMUX indica clar ADC3 si referinta AVCC cu "AVCC with external capacitor at AREF pin" exact cum a fost definit.

 

Aici ar putea sa fie "buba": eu am testat pe platforma arduino cu 328P iar nico pe platforma arduino cu atmega 328!

Daca referinta pe atmega 328 este "Reserved" iar pinul citit este A6 chiar daca a fost definit ca A3, atunci este o problema!

 

Editat de Marin1960
Link spre comentariu
1 oră în urmă, Marin1960 a spus:

ADCSRA are aceiasi valoare ca  pe Arduino Duemilanove, iar ADMUX indica clar ADC3 si referinta AVCC cu "AVCC with external capacitor at AREF pin" exact cum a fost definit

S-ar putea sa fi gresit eu cu privire la canalul ADC, cred ca am ignorat zero-ul din pozitia 8 (care lipseste) dar l-am adaugat pe pozitia 0 (rusine mie), caz in care, intr-adevar canalul ADC este 3. Dar valoarea ADCSRA este totusi gresita, indiferent daca uC are terminatia P sau nu o are, secventa bitilor 8 si 7 este "10", iar in foaia de catalog asta indica valoare rezervata. Corect ar fi fost "01" care ar fi indicat AVCC ca referinta.

Mai sapam!

 

L.E.: Cred ca am nevoie de o vacanta mai lunga. Nu este normal sa gresesc atat de flagrant. Practic tot ce am afirmat este gresit pentru ca am incurcat registrii. Functionarea ADC este corecta conform setarilor! Dar tot ramane sa mai sap, de data asta cu atentie, ca sa lamurim problema. Scuze!

Link spre comentariu

Dupa "sapat adanc" in datasheet-ul procesorului atmega 328P, am remarcat, cu surprindere doua diferente care ar putea explica "anomalia" intalnita de @messu.

 

Diferente intre Atmega 328 si Atmega 328P:
1. In "MCUCR – MCU Control Register" apar doi biti suplimantari la 328P: "Bit 6 – BODS: BOD Sleep"
 si Bit 5 – "BODSE: BOD Sleep Enable" (datasheet pag 54/662)
2. La 328P apar doua noi instructiuni de salt: "JMP k" (direct jump) si "CALL k" (Direct Subroutine Call), (datasheet pag 625/662)

 

Ei bine, daca in aplicatia respectiva se folosesc instructiunile de la punctul 2, devine clar de ce nu functioneaza pe atmega 328.

Link spre comentariu

Cred ca am identificat sursa problemei, dupa un somn odihnitor!

Cum nu am avut la indemana un encoder+ un buton + un afisor grafic (adica le am pe undeva, dar nu am timp sa le caut:)) am testat din nou programul, prin eliminarea unor subrutine pe rand si concluzia a fost ca aceste rutine:

updateMeter();
updateScreen();

s-ar parea ca creeaza problema pe ATmega328(P).

De ce? Inca nu am avut timp sa elucidez misterul! Voi verifica si pe Arduino Nano functionarea acestui program, incluzand rutinele cu pricina sa vedem care este rezultatul.

 

L.E.: si cu Arduino Nano se comporta la fel! 

L.L.E.:am pus un buton pe pinul D0 al Arduino Nano si am rulat din nou sketch-ul. Toate sunt bune si frumoase pana in momentul in care apas butonul. Pe seriala apare mesajul:

image.png.3fcc426b68dded98c149a5d6f8d048ac.png

dupa care programul ingheata. Asta ma determina sa cred ca comunicatia seriala nu se impaca cu prezenta unui buton (in cazul asta) pe unul dintre cei doi pini D0 si/sau D1.

Ca o concluzie pentru userul @messu: ori folosesti Arduino Nano, ori folosesti un adaptor I2C pentru display(MCP23017 si libraria de aici: https://github.com/nickgammon/I2C_graphical_LCD_display ). Ori schimbi display-ul cu un altul pe SPI si iar presupune schimbarea librariei.

Link spre comentariu

Cred ca nu am abordat problema bine.

De exemplu nu stiu sigur ce fel de procesor foloseste userul @messu: atmega 328 sau atmega 328P?

La un moment dat, userul respectiv zice: "cand am trecut pe ATmega 328p, treaba NU PREA mai functioneaza, sau nu functioneaza in totalitate.". Asta m-a incurcat, am citit repede si am presupus ca de fapt a trecut pe Atmega 328 nu pe acelasi tip de procesor. De aici am cautat diferente intre cele doua procesoare, dar se pare ca nu este cazul.

Daca se foloseste acelasi tip de procesor, atunci eu nu mai inteleg nimic, de unde si nedumerirea, pe buna dreptate, a initiatorului topicului.

Pe de alta parte ceva nu se leaga: daca sunt procesoare diferite avem o abordare (posibil software, vezi instructiuni diferite), daca sunt acelasi tip (doar numarul de pini difera) atunci portarea de soft sau implementarea hardware mai raman disponibile.

Parerea mea.

Link spre comentariu

Diferentele intre 328 si 328P tin de un consum mai redus (328P), de imposibilitatea dezactivarii BrownOut in software(328) si cateva instructiuni despre care nu cred ca este vorba aici. Mai degraba functionarea defectuoasa a sketch-ului pe 328P este data de ceea ce spuneam mai sus si asta ca urmare a faptului ca, utilizand 328P in capsula DIP, pierzi 2 intrari ADC (ADC6 si ADC 7), pe care autorul proiectului le-a folosit (una dintre ele).

Link spre comentariu

ATmega48P ATmega88P, ATmega168P şi ATmega328P sunt un "pic" diferite de celelalte ATmega.

La fel şi ATmega48A, ATmega88A, ATmega168A şi ATmega328.

 

Oscilatorul are un prescaler în plus şi care la pornire trebuie obligatoriu iniţializat şi poate fi folosit pentru a reduce consumul microcontrolerului în anumite momente. În unele DS nu scrie cu ce valori se iniţializează biţii CLKPS3... CLKPS0 iar în altele DS cică ar porni random ceea ce e puţin probabil.

Mai e diferită referinţa de tensiune care e de 1.10V, în timp ce la majoritatea ATmega, referinţa e de 2.56V. Mai sunt mici diferenţe şi la convertorul AD şi la interfeţe din cauza prescalerului în plus de la oscilator. Iar sistemul de întreruperi are cele mai mari diferenţe faţă de celelalte ATmega având în plus PCINT0, PCINT1 şi PCINT2.

 

Dacă e folosit un bootloader pentru ATmega328P trebuie să ştii cum setează registrul CLKPR şi să faci tot programul în funcţie de setările pe care le face bootloaderul. Pentru-că dacă umbli la CLKPR, sunt şanse mari să nu mai meargă bootloaderul.

Link spre comentariu

Am revenit cu raspunsurile .
Inainte de a va spune rezultatele probelor, fac mentiunea ca toate uC-ele sunt 328P
Cel de pe Nano si cel de pe Mini sunt 328P-AU si cel "de sine statator", in capsula DIL28 este 328P-PU.
Spun asta ca sa inlatur indoiala, intemeiata dealtfel, a lui @marin 1960.

Acum:
- tensiunea masurata la pinul Aref, este de circa 5.00V
-"incalecarea"comenzii de la encoder peste comunicarea seriala, nu mi s-a parut nici mie, de la bun inceput, o idee prea buna, insa am recurs la ea din lipsa de porturi disponibile
Sigur, as fi putut sa sacrific pinul RESET, dar am zis sa pastrez asta ca ultima optiune, asa ca am pus comanda pe pinul RX si, asa cum am spus, pe Nano, functioneaza. Cel putin din punct de vederea calitativ.
-@marin 1960, cand am folosit exprimarea "nu prea mai functioneza", pentru care dealftel imi prezint scuzele, nefiind probabil prea clara, am vrut practic ca spun ca functioneaza totul (selectia meniurilor, calibrarea, citirea
encoderului) mai putin citirea anlogica.
Acum, ca sa facem treaba si mai "frumoasa", trebuie sa va spun ca in timpul ultimelor teste am descoprit ca ADC-ul citeste ceva...totusi. Adica, pe optiunea de masurate SWR, bargraf-ul este incremenit pe o valoare fixa, indiferent ce tensiune introduc pe portul uC-ului,
in timp de in celelalte doua optiuni de masurare PWR si SNA apare o variatie a bargraf-ului. In sfrsit...n-o mai lungesc, alta ciudataenie.
-@marin 1960, inlocuirea int r = analogRead(DBM_READING); cu int r = 512; nu a produs nicio schimbare la optiunea SWR. Se vede o schimbare la optiunile PWR si SNA, dar nici aia nu cred ca este corecta .

In final trebuie sa spun ca am incercat si punerea bootloaderului de Nano (via ICSP) si pe Mini si pe 328P-DIL28 dupa care am incarcat sketch-ul via USB-TTL ca sa recreez modul de incarcare din Arduino Nano.
Rezultatul este, incredibil pentru mine, ACELASI !!!
Pe optiunea SWR, bargraf-ul este intepenit pe 99.9, ORICE AS FACE.
Mai am un Arduino Nano la indemana, asa ca am sa fac o proba si pe el ca sa vedem cum se comporta.
Oricum ar fi, pare ca Arduino Nano este singurul care suporta acest proiect, iar motivul ma depaseste TOTAL. 

 

https://youtube.com/shorts/wI2H4rAB6Tc?feature=share

 

In Video de mai sus este la lucru Arduino Nano si se poate vedea clar cum valoarea numerica variaza de la 1.00 la 99.9, la fe si indicatia de pe bargraf atunci cand rotesc de potentiometrul.
La celalalte uC-uri (Mini si DIL) valoarea este fixa 99.9 :(

Link spre comentariu

Am facut proba si pe celalalt Arduino Nano si....merge citirea pe ADC. Curios este ca apare o alta problema ciudata la meniu.

Cred ca am sa incerc sa completez circuitul si cu SI5351 ca sa fie toata partea digitala completa. Ma gandesc sa nu fie vreo problema si din cauza asta... 

Link spre comentariu

Gata. I-am dat de cap !

Nu era de la cod, subrutine, fusebiti, nimic. 

Era de la...EEPROM. Adica de la ce este scris in el.

In mod normal, aplicatia in cauza fiind un aparat de masura, pentru utilizarea lui se face o calibrare ale carei rezultate se stocheaza in EEPROM si sint folosite la calculele ulterioare.

M-au tot sucit pe toate partile si m-am gandit ca de acolo ar putea fi problema, asa ca am copiat continutul EEPROM-ului de pe Nano care functiona, pe celelalte uC. De unde continutul EEPROM-ului de pe Nano fara a face o calibrare?

Probabil niste date, cumva aleatorii, stocate la utilizarea cu alte ocazii in alte aplicatii cu ceva vreme in urma, care au fost numai bune ca sa demonstreze functionarea, fara insa a fi si corect dpdv. metrologic.

Acum toate funtioneza perfect. Ma duc sa ma culc, ca e 1.45 si stau pe ele si ma perpelesc de la 5 dupa amiaza :)

Va multumesc tuturor pentru sugestii si implicare !

Link spre comentariu

Felicitari pentru efort. Probabil ca problema intampinata ar fi putut fi evitata daca autorul ar fi prevazut ca procedura de calibrare sa fie primul pas inainte de utilizare. Dar fiecare isi scrie programele cum crede!

 

Link spre comentariu
Acum 10 ore, messu a spus:

Era de la...EEPROM. Adica de la ce este scris in el.

Nu inteleg care a fost motivul pentru care nu ai publicat codul complet.
Chiar ai fost sfatuit sa testezi numai portiunea de cod referitoare la ADC.
S-au chinuit ceva persoane sa te ajute si s-au umplut trei pagini degeaba.

Link spre comentariu

Creează un cont sau autentifică-te pentru a adăuga comentariu

Trebuie să fi un membru pentru a putea lăsa un comentariu.

Creează un cont

Înregistrează-te pentru un nou cont în comunitatea nostră. Este simplu!

Înregistrează un nou cont

Autentificare

Ai deja un cont? Autentifică-te aici.

Autentifică-te acum



×
×
  • Creează nouă...

Informații Importante

Am plasat cookie-uri pe dispozitivul tău pentru a îmbunătății navigarea pe acest site. Poți modifica setările cookie, altfel considerăm că ești de acord să continui.Termeni de Utilizare si Ghidări