Ich versuch seit einer geschlagenen Woche diesen Drecks-Wandler zum Laufen zu bringen - unmöglich! Und beim Googeln hab ich zig Leute gefunden, die ähnliche Probleme haben. Ich will nichts weiter, als die 4 Kanäle des A/D-Wandlers über I2C-Bus auslesen. Ich verwende sogar die offizielle I2C-Biliothek von Microchip: char readAD(char devadr,char channel) { unsigned char n; // write control word to PCF8591 IdleI2C(); StartI2C(); while ( SSPCON2bits.SEN ); // wait until START condition over IdleI2C(); WriteI2C(0x90 | (devadr<<1)); IdleI2C(); WriteI2C(0x40 | channel); IdleI2C(); StopI2C(); while ( SSPCON2bits.PEN ); // wait until stop condition is over // Read A/D channel IdleI2C(); StartI2C(); while ( SSPCON2bits.SEN );//wait until start condition over WriteI2C((0x91 )| (devadr<<1))); IdleI2C(); ReadI2C(); // don't use first value read IdleI2C(); AckI2C(); IdleI2C(); n = ReadI2C(); IdleI2C(); NotAckI2C(); IdleI2C(); StopI2C(); while (SSPCON2bits.PEN);// wait until stop condition is over return (unsigned char) n; } 3 von 4 Kanälen kann ich so wunderbar auslesen. Nur einer spinnt rum: Kanal 2 geht nicht bis auf 0 runter. Selbst wenn ich ihn auf Masse lege, gibt der Wandler 55 zurück. Was noch schlimmer ist: Dieser Kanal wird irgendwie von Kanal 1 beeinflusst; wenn ich an Kanal 1 die Spannung erhöhe, wächst auch der Wert von Kanal 2. Es wäre ja naheliegend, dass ich das Controlbyte irgendwie falsch eingestellt habe, und der PCF8591 auf differentielle Eingänge eingestellt ist - nur: laut Datenblatt gibts überhaupt keine Konfiguration, wo Kanal 1 und 2 differenziell geschaltet sind! Ich werd echt noch wahnsinnig. Hab den IC schon 2x ausgetauscht weil ich dachte ok, vielleicht hab ich den vorher mal zerschossen - aber genau dasselbe! Zusammen mit der Tatsache, dass ich bei RS-Komponents diese Mistdinger für insg. 25 Euro gekauft habe werd ich echt langsam sauer...
Hier zur Einfachheit halber nochmal im Pseudocode, was ich auf dem Bus mache: START WRITE PCF8591_WRITE_ADDRESS WRITE CONTROL_BYTE (0x40) STOP START WRITE PCF8591_READ_ADDRESS READ ACK value := READ NACK STOP return value
hallo kowalskowski, ich hatte auch das problem das die kanäle ab und zu spinnen. es ist wichtig das der ad-mode auf 4 single ended inputs steht (müsste laut deinem statuswort ja auch so sein). bei mir hab ich wohl immer den dac aus (also statuswort auf 0x00). das einzige problem was ich habe ist das die kanäle bei mir verwürfelt sind. hier mal mein code fragment : VOID BD_vGetFaders (UCHAR *pucValues) { UCHAR ucC, ucV, ucBuff; for (ucC = 0; ucC < 8; ucC ++) { BD_vRD_I2C_Start (); ucBuff = BD_ucI2C8591WriteAddress (ucC >> 2); BD_bWR_I2C (1, (UCHAR *) &ucBuff); // control - wort für adc setzen ucBuff = (ucC & 0x03) << 0 | // kanal 0 << 2 | // kein autoincrement 0 << 4 | // 4 single-ended inputs 0 << 6 ; // kein dac BD_bWR_I2C (1, (UCHAR *) &ucBuff); BD_vRD_I2C_End (); BD_vRD_I2C_Start (); ucBuff = BD_ucI2C8591ReadAddress (ucC >> 2); BD_bWR_I2C (1, (UCHAR *) &ucBuff); ucBuff = BD_bRD_I2C (1, (UCHAR *) &ucV); BD_vRD_I2C_End (); switch (ucC) { case 0 : pucValues [3] = ucV; break; case 1 : pucValues [0] = ucV; break; case 2 : pucValues [1] = ucV; break; case 3 : pucValues [2] = ucV; break; case 4 : pucValues [7] = ucV; break; case 5 : pucValues [4] = ucV; break; case 6 : pucValues [5] = ucV; break; case 7 : pucValues [6] = ucV; break; default: break; } } } Gruß Rene
case 0 : pucValues [3] = ucV; break; case 1 : pucValues [0] = ucV; break; case 2 : pucValues [1] = ucV; break; case 3 : pucValues [2] = ucV; break; Sieht aus als wäre es um 1 versetzt, weil man ja wenn man vom Wandler liest, immer den letzten Wert kriegt. Also wenn Du Kanal 1 selektierst und den Wandler ausliest, dann fängt er da erst an Kanal 1 zu wandeln, gibt Dir aber den Wert des letzten Samples zurück (in dem Fall von Kanal 0). Du könntest versuchen, einfach 2x zu lesen und den ersten Wert wegschmeissen, dann müsste das mit dem Umsortieren unnötig werden. Ansonsten herzlichen Glückwunsch dass Du schon so weit gekommen bist!!! :) bin da noch meilenweit von entfernt Was mir auffällt, Du sendest gar kein NACK nach dem letzten Lesen. Braucht man vielleicht auch nicht, wenn Du nur einen Wert liest, weil danach die STOP-Bedingung kommt.
Ich hatte diesen Wandler auch mal verwendet. Nach einer Woche habe ich das Drecksteil entsorgt. Zum Glück gibt es genügend andere ADC mit SPI o.ä. und zum Glück haben AVRs ADCs eingebaut... Was spricht eigentlich dagegen einen AVR als ADC zu verwenden ? Man kann ja einen Software I2C oder SPI Slave einbauen (oder den USI verwenden) und so die Daten auslesen.
Ganz einfach: Ich brauch nicht einen Wandler, auch nicht 2, sondern 12 Stück! Ich hatte schon mit dem Gedanken gespielt, CD4066 analoge Switches zu benutzen, um die zu messenden Pegel nacheinander auf den ADC zu schalten. Problem ist nur: ich hab kaum noch I/Os frei. Also brauch ich dafür nen Schieberegister mit Latch, frisst wieder 3 Pins und 1 IC mehr auf der Platine; dann noch 1-of-16 decoder um einen der Switche auszuwählen => noch ein IC auf der Platine (und die Dinger sind richtig eklig fett). Ich hatte das sogar mal aufgebaut und hat auch geklappt, aber ich hab keinen Platz mehr auf der Platine! Für diese Lösung brauch ich nämlich: 3x4066 1xSchieberegister 1xDecoder macht 5 ICs. Nein danke.
LTC1290 hat 8 umschaltbare Eingänge, gibts bei den üblichen Verdächtigen zu kaufen. 12 Bit seriell 50 kHz Durchsatzrate, den hab ich schon in Assembler auf AVR benutzt. http://www.linear.com/pc/productDetail.do?navId=H0,C1,C1155,C1001,C1158,P1594
Hallo Kowalkowski, also bis auf diesen versatz (um einen Kanal) hatte ich eigentlich keine größeren Probleme mit dem PCF8591. Hab den schon vor Jahren benutzt und der hats immer getan. Kanns denn vielleicht sein das in der beschaltung was nicht ok ist ? Was mit softwaremässig noch einfällt : Ich hatte kurzzeitig mal probleme. Das lag daran das ich einen Software-I2C verwendet habe und der einfach zu schnell war. Da kamen dann auch ganz komische effekte bei raus. Sonst mach doch mal einfach eine SW-I2C und das gaaaanz langsam (I2C geht ja runter bis DC). Wäre ja echt ärgerlich wenn du deine ganzen PCFs wegschmeißen kannst. Gruß Rene PS. Mal eine Frage zu den SPI-Wandlern. Gibt es kostengünstige A/D Wandler mit SPI ? Mit kostengünstig meine ich ca. 1/5 oder 1/10 des preises was ein PCF8591 (ca 3 Euros) kostet ? Die Geschwindigkeit ist egal (selbst 2kHz bei 8bit reichen) es geht nur um fader und Potis ...
>Gibt es kostengünstige A/D Wandler mit SPI Da wäre z.B. meine Idee mt dem AVR: Ein ATTiny26 bietet 10x 10bit ADCs. Ein SPI Interface kann man mit dem USI leicht bauen. Das ganze kostet dann 2. Wenn man mehr Kanäle braucht, hängt man halt noch ein paar Multiplexer dran, die der AVR ansteuert. So kann man leicht 20 und mehr Kanäle erreichen.
Hi, nichts für ungut, aber ich habe Riesenprobleme mit dem LTC1290 gehabt, obwohl da auch Bausätze angeboten werden... (siehe ELV oder Conrad) Mein Favorit ist der von TI ADS7828, der hat I2C, kostest ca. 6-8 Euro und ist SMD. Kann 8 Kanäle und funktionierte mit AVR Mega. (AVR Experimentierboard aufgebaut und Adapter Platine gelötet; insgesamt mit viel Ruhe ca. 1 Stunde...) Zum PCF kann ich nichts direktes sagen, da das alles auf den ersten Blick gut aussieht. Ich unterstütze aber das mit dem Timing. Wenn Du zu schnell arbeitest treten bei bestimmten ICs solche Nebeneffekte auf. Versuchen mal mit Delays die Taktrate runterzusetzen... Gruß Sven
Hallo Benedikt, prinzipiell würde ich dir ja auch zustimmen. Ich weiß nur nicht ob sich das rechnet. Man benötigt für einen AVR-ADC-mit-irgendwas-Interface ja auch immer eine Platine (je nachdem welchen AVR man verwendet) und mit der Platine ists ja auch nicht getan. Der uC will ja auch noch seine SW. Und wie ich gestern erfahren hab ist das mit dem Debugging von AVRs ja so eine Sache. Also ich weiß nicht ob der Preisunterschied von sagen wir mal 4 Euro (2 PCF8591 = 8 Kanäle = 6Euro <-> AVR 8-10 Kanäle = 2 Euro) die Software "mal eben" enstehen lässt. Zumal man dann ja an 2 Baustellen gleichzeitig ist, während man bei fertigen Chips (bis auf eventuelle Hardware-Fehler, die beim AVR aber genausoauftreten können) nur noch 1 Baustelle hat. @kowalkowski : Ich hab gerade noch einen evtl. interessanten Wandler gefunden : TLC541. Scheint ganz lustig zu sein. Problem : der braucht 2 Takte (System-Takt und IO-Takt), aber den kann man ja evtl. in einem bestehenden System an einen Port Pin erzeugen, da der System-Takt wie der IO Takt praktisch (laut Datenblatt) bis zu DC runtergehen kann. Und was ich ganz praktisch finde : Ich brauche keine neg. Versorgungsspannung. Für was für eine Anwendung brauchst du denn soviele Kanäle ? Poti/Fader Feld ?! :-) Gruß Rene
ach ja ... zum thema tlc540/tlc541 noch was ... 11 kanäle (allerdings multiplexed) und bei reichelt 2,80 euros (zwar nicht billiger, aber dafür knapp 3mal soviele eingänge :-)))
Mhmm darf man die Taktrate beliebig einstellen? Ich dachte es gibt nur 3 verschiedene Versionen: 100Khz, 400Khz und 1.irgendwas Mhz (high-speed). Aber guter Tip, ich versuch mal das runterzuschrauben. Laut Datenblatt sollte der aber 100Khz vertragen... Software-I2C könnte ich zur Not auch machen; gibts jede Menge Sourcecode für, aber der PIC hat das hardwaremäßig und wäre unsinn das nicht auch zu benutzen! Zur Beschaltung: Ich hab 2x 10K Pull-Up's in der Daten und Taktleitung, sonst eigentlich nix besonderes. Als Referenzspannungsquelle eine Zenerdiode, allerdings ungepuffert; der PCF zieht aber laut DB nur einige Mikroampere.
Die Kanäle brauch ich für mein digitales symmetrisches Netzteil: 2x Spannung & Strom messen für + und - Ausgang (macht 4 Kanäle), dann noch Festspannungen (5V,12V,15V) je Spannung und Strom macht nochmal 6, und noch welche um das Poti auszulesen.
I2C kannsde auch mit 1Hz machen wenn du lustig bist (und zeit hast)... meine probleme bei I2C waren zB, dass die STOP Cond. zu schnell erzeugt wurde... also die flanken von SDA und SCL zu schnell hintereinander kamen... das wird bei dir aber nicht der fall sein, da ja nur ein kanal spinnt...
hallo kowalkowski, also hw-i2c sollte es auch tun (obwohl ich es bis jetzt noch nicht ausprobiert habe, da ich keinen prozi habe der hw-i2c hat, nutze den msp430f149). aber 1.irgendwas MHz kann der PCF keinesfalls. hatte mit dem r8c board aus der elektor mein i2c grab (3 pcf8574 und 2 pcf8591) per sw-i2c angesteuert. ohne delay funktionierten nur die 8574, aber die 8591 haben rumgesponnen. nach groben überschlagen kam ich dann zu der einsicht das ich mit mehr als 400kHz arbeite, und das mögen die wohl nicht. nach einfügen einiger nop's funktionierten dann auch die 8591 tadellos. interessantes projekt dein universal-netzteil. wie hast du denn die strom-messung gemacht ? einfach nen shunt und dann nen op dahinter ? mich würde sowas auch interessieren, allerdings bin ich eher auf der suche nach einem ic das in strom und spannung regelbar ist, aber ob sich der aufwand für mich lohnt weiß ich noch nicht. mal schauen gruß rene
Shunt iss gut, bei geplanten 20A kannste das vergessen - selbst bei 0.1Ohm kannste den als Heizung benutzen ;) Ein genau abgemessenes Stück Draht auf der Platine, mit OP-Amp gepuffert, mehr nicht. Bessere Lösung wäre ein Hallsensor, aber die sind sauteuer (15 Euro). Dann lieber ein Stück Kupferdraht :)
Die Stromregelung ist übrigens sehr einfach zu realisieren; man koppelt einen Teil der am Shunt/Draht abgefallenen Spannung zurück auf einen Transistor, der dem Längstransistor den Basisstrom "klaut". Ab Überschreiten der Schwellspannung kann der Längstransistor nicht mehr weiter aufmachen, und der Strom kann nicht steigen. Den Maximalstrom kann man mit einem Poti einstellen, welcher die am Shunt abgefallene Spannung runterteilt. Übrigens: Die brutalste Lösung für ein 20A Netzteil sind einfach 20 78319 einstellbare Spannungsregler auf ein fettes Kühlblech zu packen :))) Besser wäre es, anstatt eines Längstransistors einen FET zu nehmen, aber da fehlt mir noch das nötige Wissen zu...
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.