Incepator92 Postat Decembrie 6, 2016 Partajează Postat Decembrie 6, 2016 (editat) Buna ziua, Am achizitionat de curand un convertor analog numeric si anume LTC2418 si o referinta de tensiune LT1236. As dori sa il folosesc impreuna cu o placa de dezvoltare arduino mega cu care m-am mai jucat pana acum dar am facut doar aplicatii simple. Am ales acest ADC deoarece are rezolutie mare (24 biti) si am gasit ceva documentatie pentru el plus ceva cod pentru arduino dar care nu functioneaza si pe care nu il inteleg. Acum sa o luam cu inceputul (cu cateva specificatii): -Tensiune de alimentare (2.7v-5.5v) eu il alimentez la 5v -Are un oscilator intern dar se poate folosi si unul extern (eu aleg sa folosesc clock-ul furnizat de acesta) Note 7: FO = 0V (internal oscillator) or fEOSC = 153600Hz ±2% (external oscillator). Note 8: FO = VCC (internal oscillator) or fEOSC = 128000Hz ±2% (external oscillator). -Poate matura in intervalul (-vref/2 - +vref/2) in cazul meu -2.5v si 2.5v deoare ce am ales o referinta de 5v Mai jos am atasat diagrama de timming : Tot ce am facut pana acum sunt urmatoarele . Am alimentat circuitul si am atasat referinta de tensiune, am pus in 0 pinul FO si am observat ca daca trec simultan si pinul cs in low am o secventa de clock pe pinul SCK de 32 de biti conform diagramei de mai sus. Eu trebuie sa ma sincronizez cu acest clock generat de adc si trebuie sa ii dau urmatoarele secvente de biti : Pn mine nu ma intereseaza deocamdata sa citesc tensiuni flotante. Ma intereseaza sa citesc tensiuni fata de pinul com asa ca mai jos am pus secventele de biti pt toate cele 16 canale in parte (valorile sunt duplicate deoare ce trebuie sa dureze o perioada de clock e o prostie de a mea) : int ch0[]={1,1, 0,0, 1,1, 1,1, 0,0, 0,0, 0,0, 0,0, }; int ch1[]={1,1, 0,0, 1,1, 1,1, 1,1, 0,0, 0,0, 0,0, }; int ch2[]={1,1, 0,0, 1,1, 1,1, 0,0, 0,0, 0,0, 1,1, }; int ch3[]={1,1, 0,0, 1,1, 1,1, 1,1, 0,0, 0,0, 1,1, }; int ch4[]={1,1, 0,0, 1,1, 1,1, 0,0, 0,0, 1,1, 0,0, }; int ch5[]={1,1, 0,0, 1,1, 1,1, 1,1, 0,0, 1,1, 0,0, }; int ch6[]={1,1, 0,0, 1,1, 1,1, 0,0, 0,0, 1,1, 1,1, }; int ch7[]={1,1, 0,0, 1,1, 1,1, 1,1, 0,0, 1,1, 1,1, }; int ch8[]={1,1, 0,0, 1,1, 1,1, 0,0, 1,1, 0,0, 0,0, }; int ch9[]={1,1, 0,0, 1,1, 1,1, 1,1, 1,1, 0,0, 0,0, }; int ch10[]={1,1, 0,0, 1,1, 1,1, 0,0, 1,1, 0,0, 1,1, }; int ch11[]={1,1, 0,0, 1,1, 1,1, 1,1, 1,1, 0,0, 1,1, }; int ch12[]={1,1, 0,0, 1,1, 1,1, 0,0, 1,1, 1,1, 0,0, }; int ch13[]={1,1, 0,0, 1,1, 1,1, 1,1, 1,1, 1,1, 0,0, }; int ch14[]={1,1, 0,0, 1,1, 1,1, 0,0, 1,1, 1,1, 1,1, }; int ch15[]={1,1, 0,0, 1,1, 1,1, 1,1, 1,1, 1,1, 1,1, }; Acum trebuie sa sransmit prin SPI si sa citesc totodata sincronizat cu clockul ei. Nu am folosit pana acum aceasta comunicatie si am nevoie de ajutor. Bine inteles ca am citit pe internet tot felul de exemple dar in cazul meu ADC este master si arduino ar trebui sa fie Slave. Am atasat mai jos linkul cu librariile gasite dar pe care nu stiu sa le folosesc. https://github.com/JQIamo/LTC2418-arduino Editat Decembrie 6, 2016 de Incepator92 Link spre comentariu
ratza Postat Decembrie 9, 2016 Partajează Postat Decembrie 9, 2016 De ce vrei neapărat să foloseşti ADC-ul ca master? Te complici inutil. Link spre comentariu
deejay2k1 Postat Decembrie 9, 2016 Partajează Postat Decembrie 9, 2016 (editat) cam asta este ideea mea. in principu, pe frontul cresctor al sck scrii un bit din byte-ul de selectie, iar pe frontul crescator al cs-ului treci la urmatorul byte de selectie canal de compilat compileaza, insa nu am pe ce sa o testez. #define sck 2 #define sdi 3 #define cs 4 const byte channel[] = {0xb0, 0xb8, 0xb1, 0xb9, 0xb2, 0xba, 0xb3, 0xbb, 0xb4, 0xbc, 0xb5, 0xbd, 0xb6, 0xbe, 0xb7, 0xbf}; bool cs_now = true; bool cs_mem = true; bool sck_now = false; bool sck_mem = false; byte currentChannel = 0; byte currentBit = 0; void setup() { pinMode(sck, INPUT); pinMode(cs, INPUT); pinMode(sdi, OUTPUT); } void loop() { cs_now = digitalRead(cs); sck_now = digitalRead(sck); if (cs_now & (cs_now ^ cs_mem)) { currentChannel++; currentBit = 0; currentChannel %= 8; } if (!cs_now) { if (sck_now & (sck_now ^ sck_mem)) { digitalWrite(sdi, bitRead(channel[currentChannel], currentBit)); currentBit++; currentBit %= 8; } } cs_mem = cs_now; sck_mem = sck_now; } Editat Decembrie 9, 2016 de deejay2k1 Link spre comentariu
Incepator92 Postat Decembrie 9, 2016 Autor Partajează Postat Decembrie 9, 2016 (editat) Multumesc de ajutor. Pinul cs (chip select) este de intrare. La punerea lui in 0 porneste adc si furnizeaza secventa de clock peste care trebuie sa vin eu cu datele de intrare. Nu prea imi dau seama 100 % cum sa modific codul dumneavoastra . Editat Decembrie 9, 2016 de Incepator92 Link spre comentariu
deejay2k1 Postat Decembrie 9, 2016 Partajează Postat Decembrie 9, 2016 ok, pai atunci incearca sa incepi cu ceva mai usor oricum , incearcsa asa: #define sck 2#define sdi 3#define cs 4#define sdo 5const byte channel[] = {0xb0, 0xb8, 0xb1, 0xb9, 0xb2, 0xba, 0xb3, 0xbb, 0xb4, 0xbc, 0xb5, 0xbd, 0xb6, 0xbe, 0xb7, 0xbf};long channelValues[sizeof(channel)];bool cs_now = true;bool cs_mem = true;bool sck_now = false;bool sck_mem = false;byte currentChannel = 0;byte currentBit = 0;void setup() { pinMode(sck, INPUT); pinMode(sdo, INPUT); pinMode(cs, OUTPUT); pinMode(sdi, OUTPUT); Serial.begin(9600);}void loop() { static long nextRun = 0; if (millis() > nextRun) { nextRun = millis(); for (int currentChannel = 0; currentChannel < sizeof(channel); currentChannel++) { digitalWrite(cs, LOW); currentBit = 0; byte bitReads = 0; do { sck_now = digitalRead(sck); if (sck_now & (sck_now ^ sck_mem)) { digitalWrite(sdi, bitRead(channel[currentChannel], currentBit)); bitWrite(channelValues[currentChannel], bitReads, digitalRead(sdo)); currentBit++; currentBit %= 8; bitReads++; } sck_mem = sck_now; } while (bitReads < 32); digitalWrite(cs, HIGH); Serial.print("CH_"); Serial.print((channelValues[currentChannel] & 0x0000000e) >> 1); Serial.print(" value ="); Serial.print((channelValues[currentChannel] & 0x1fffffc0) >> 6); } }} Link spre comentariu
Incepator92 Postat Decembrie 22, 2016 Autor Partajează Postat Decembrie 22, 2016 (editat) Salut. Am reusit sa fac adc-ul sa functioneze folosind un cod de la ei pe care l-am modificat aliminand din el ceea ce nu ma intereseaza. #include <Arduino.h>#include <stdint.h>#include "Linduino.h"#include "LT_SPI.h"#include "LT_I2C.h"#include "UserInterface.h"#include "QuikEval_EEPROM.h"#include "LTC2418.h"#include <SPI.h>#include <Wire.h>int8_t menu_1_read_single_ended();static uint8_t demo_board_connected; //!< Set to 1 if the board is connectedstatic float LTC2418_lsb = 5.9604652E-7; //!< Ideal LSB voltage for a perfect partstatic int32_t LTC2418_offset_code = 0; //!< Ideal offset for a perfect partconst uint8_t BUILD_COMMAND_SINGLE_ENDED[16] = {LTC2418_CH0, LTC2418_CH1, LTC2418_CH2, LTC2418_CH3, LTC2418_CH4, LTC2418_CH5, LTC2418_CH6, LTC2418_CH7, LTC2418_CH8, LTC2418_CH9, LTC2418_CH10, LTC2418_CH11, LTC2418_CH12, LTC2418_CH13, LTC2418_CH14, LTC2418_CH15 }; const uint16_t MISO_TIMEOUT = 1000; void setup(){ char demo_name[6]="DC571"; // Demo Board Name stored in QuikEval EEPROM quikeval_SPI_init(); // Configure the spi port for 4MHz SCK quikeval_SPI_connect(); // Connect SPI to main data port quikeval_I2C_init(); // Configure the EEPROM I2C port for 100kHz Serial.begin(115200); // Initialize the serial port to the PCdemo_board_connected = discover_demo_board(demo_name); }void loop(){ { uint8_t adc_command; // The LTC2418 command byte int16_t user_command; // The user input command uint32_t adc_code; // The LTC2418 code float adc_voltage; // The LTC2418 voltage while (1) { adc_command = BUILD_COMMAND_SINGLE_ENDED[0]; // Build ADC command for channel 0 if(LTC2418_EOC_timeout(LTC2418_CS, MISO_TIMEOUT)) // Check for EOC return(1); LTC2418_read(LTC2418_CS, adc_command, &adc_code); // Throws out last reading for (int8_t x = 0; x <= 15; x++) { adc_command = BUILD_COMMAND_SINGLE_ENDED[(x + 1) % 16]; // Read all channels in single-ended mode if(LTC2418_EOC_timeout(LTC2418_CS, MISO_TIMEOUT)) // Check for EOC return(1); LTC2418_read(LTC2418_CS, adc_command, &adc_code); adc_voltage = LTC2418_code_to_voltage(adc_code, LTC2418_lsb , LTC2418_offset_code); Serial.print(F("CH")); Serial.print(x); Serial.print(F(": ")); Serial.print(adc_voltage, 4); Serial.print(F("Vn")); } }}} Acum ma confrunt cu urmatoarea problema. As vrea sa execut ceea ce este in bucla while o data la 10 secunde . Deci ar trebui sa fac o intrerupere interna .Am incercat eu ceva dar nu a mers. Ideea e ca eu vreau sa masor capacitatea unor baterii si pe baza acelui timer care genereaza intreruperile trebuie sa contorizez timpul. Cum pot genera o intrerupere interna ? Mentionez ca folosesc arduinoo uno acum . Editat Decembrie 22, 2016 de Incepator92 Link spre comentariu
Liviu M Postat Decembrie 22, 2016 Partajează Postat Decembrie 22, 2016 Incearca cu millis(). Salvezi valoarea returnata de millis() la ultima executie (int32_t lastExecTimeStamp) si pentru o noua executie testezi daca millis() - lastExecTimeStamp) > 10000. Link spre comentariu
Incepator92 Postat Decembrie 22, 2016 Autor Partajează Postat Decembrie 22, 2016 Multumesc de ajutor. Functioneaza. Sper sa nu intalnesc si alte probleme . Link spre comentariu
Liviu M Postat Decembrie 22, 2016 Partajează Postat Decembrie 22, 2016 (editat) Probleme... millis() se reseteaza/o ia de la capat la ~50 de zile. Daca vrei ca programul sa lucreze continuu > 50 de zile, trebuie sa detectezi si sa tratezi corect situatia asta. Editat Decembrie 22, 2016 de Liviu M Link spre comentariu
Incepator92 Postat Decembrie 22, 2016 Autor Partajează Postat Decembrie 22, 2016 Nu este nici o problema . Dureaza cateva ore sa masor capacitatea bateriilor .Nu va fi nici o problema Link spre comentariu
Incepator92 Postat Decembrie 23, 2016 Autor Partajează Postat Decembrie 23, 2016 Salut. Ies un pic in afara discutiei. Cunoaste cineva un circuit integrat formator de semnal care dintr-un semnal care sta in HI 10% dintr-o perioada si in LOW 90% dintr-o perioada sa imi faca un semnal dreptunghiular cu factor de umplere 50% ? Link spre comentariu
nico_2010 Postat Decembrie 23, 2016 Partajează Postat Decembrie 23, 2016 Monostabil 74HC123, dar asta este si functie de frecventa semnalului, precum si de nivelul de tensiune al acestuia. Sunt mai multe detalii de analizat... Link spre comentariu
UDAR Postat Decembrie 23, 2016 Partajează Postat Decembrie 23, 2016 Riguros problema o rezolvi cu un PLL ( sau altă variantă de multiplicare cu 2 ) urmat de un bistabil care divide cu 2. Dar , cum spune colegul mai sus , sunt mai multe detalii de analizat . Și pentru asta ar trebui să le furnizezi .... Link spre comentariu
Liviu M Postat Decembrie 23, 2016 Partajează Postat Decembrie 23, 2016 Intr-un topic nou (eventual la alta sectiune), ca n-are nici o legatura cu arduino. Link spre comentariu
Incepator92 Postat Decembrie 29, 2016 Autor Partajează Postat Decembrie 29, 2016 Salut Liviu ai dreptate. Am deschis un topic nou. Linkul este mai jos : http://www.elforum.info/topic/121765-adaptare-driver-la-controller-uc100/ Sarbatori fericite ! Link spre comentariu
Postări Recomandate
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 contAutentificare
Ai deja un cont? Autentifică-te aici.
Autentifică-te acum