Code pour un ADC par SPI (LTC2400)

Bonjour!

J’ai reçu il y a peu un circuit imprimé avec un LTC2400 (un ADC 24 bits utilisant le bus SPI) mais je suis confronté à un problème de taille : je ne trouve aucun code pouvant le faire marcher.

Voici la bête :

J’ai tenté d’utiliser le code fourni mais il ne marche pas car il n’y a aucune librairie “stdio.h” et je n’arrive pas à la trouver sur le net :

//LTC2400 24bit ADC Module 
//
//Application Demo: 7 digit voltmeter 
//24bit ADC IC: LTC2400
//4.096 precision reference: TI REF3040
//
//By coldtears electronics
//
//LTC2400 code is adapted from Martin Nawrath
//Kunsthochschule fuer Medien Koeln
//Academy of Media Arts Cologne
//


#include <Stdio.h>
#include <stdlib.h>


#ifndef cbi
#define cbi(sfr, bit)     (_SFR_BYTE(sfr) &= ~_BV(bit))
#endif
#ifndef sbi
#define sbi(sfr, bit)     (_SFR_BYTE(sfr) |= _BV(bit))
#endif

#define LTC_CS 22         // LTC2400 Chip Select Pin  on Portb 2
#define LTC_MISO 50      // LTC2400 SDO Select Pin  on Portb 4
#define LTC_SCK 52       // LTC2400 SCK Select Pin  on Portb 5


void setup() {

 cbi(PORTB,LTC_SCK);      // LTC2400 SCK low
 sbi (DDRB,LTC_CS);       // LTC2400 CS HIGH

 cbi (DDRB,LTC_MISO);
 sbi (DDRB,LTC_SCK);

 Serial.begin(38400);
 
 // init SPI Hardware
 sbi(SPCR,MSTR) ; // SPI master mode
 sbi(SPCR,SPR0) ; // SPI speed
 sbi(SPCR,SPR1);  // SPI speed
 sbi(SPCR,SPE);   //SPI enable

 //Serial.println("LTC2400 ADC Test");

}
float volt;
float v_ref=4.094;          // Reference Voltage, 5.0 Volt for LT1021 or 3.0 for LP2950-3

long int ltw = 0;         // ADC Data ling int
int cnt;                  // counter
byte b0;                  //
byte sig;                 // sign bit flag
char st1[20];             // float voltage text

/********************************************************************/
void loop() {

 cbi(PORTB,LTC_CS);             // LTC2400 CS Low
 delayMicroseconds(1);
 if (!(PINB & (1 << 4))) {    // ADC Converter ready ?
   //    cli();
   ltw=0;
   sig=0;

   b0 = SPI_read();             // read 4 bytes adc raw data with SPI
   if ((b0 & 0x20) ==0) sig=1;  // is input negative ?
   b0 &=0x1F;                   // discard bit 25..31
   ltw |= b0;
   ltw <<= 8;
   b0 = SPI_read();
   ltw |= b0;
   ltw <<= 8;
   b0 = SPI_read();
   ltw |= b0;
   ltw <<= 8;
   b0 = SPI_read();
   ltw |= b0;

   delayMicroseconds(1);

   sbi(PORTB,LTC_CS);           // LTC2400 CS Low

   if (sig) ltw |= 0xf0000000;    // if input negative insert sign bit
   ltw=ltw/16;                    // scale result down , last 4 bits have no information
   volt = ltw * v_ref / 16777216; // max scale
   char tmp[10];
   dtostrf(volt,6,6,tmp);
   tmp[8]='V';
   tmp[9]='\n';
  Serial.print(cnt++);
  Serial.print(";  ");
  printFloat(volt,6);           // print voltage as floating number
  Serial.println("  ");

  
 }
 sbi(PORTB,LTC_CS); // LTC2400 CS hi
 delay(20);

}
/********************************************************************/
byte SPI_read()
{
 SPDR = 0;
 while (!(SPSR & (1 << SPIF))) ; /* Wait for SPI shift out done */
 return SPDR;
}
/********************************************************************/
//  printFloat from  tim / Arduino: Playground
// printFloat prints out the float 'value' rounded to 'places' places
//after the decimal point
void printFloat(float value, int places) {
 // this is used to cast digits
 int digit;
 float tens = 0.1;
 int tenscount = 0;
 int i;
 float tempfloat = value;

 // if value is negative, set tempfloat to the abs value

   // make sure we round properly. this could use pow from
 //<math.h>, but doesn't seem worth the import
 // if this rounding step isn't here, the value  54.321 prints as

 // calculate rounding term d:   0.5/pow(10,places)
 float d = 0.5;
 if (value < 0)
   d *= -1.0;
 // divide by ten for each decimal place
 for (i = 0; i < places; i++)
   d/= 10.0;
 // this small addition, combined with truncation will round our

 tempfloat +=  d;

 if (value < 0)
   tempfloat *= -1.0;
 while ((tens * 10.0) <= tempfloat) {
   tens *= 10.0;
   tenscount += 1;
 }

 // write out the negative if needed
 if (value < 0)
   Serial.print('-');

 if (tenscount == 0)
   Serial.print(0, DEC);

 for (i=0; i< tenscount; i++) {
   digit = (int) (tempfloat/tens);
   Serial.print(digit, DEC);
   tempfloat = tempfloat - ((float)digit * tens);
   tens /= 10.0;
 }

 // if no places after decimal, stop now and return
 if (places <= 0)
   return;

 // otherwise, write the point and continue on
 Serial.print(',');

 for (i = 0; i < places; i++) {
   tempfloat *= 10.0;
   digit = (int) tempfloat;
   Serial.print(digit,DEC);
   // once written, subtract off that digit
   tempfloat = tempfloat - (float) digit;
 }
}

J’ai beau chercher sur internet et essayer plusieurs autres codes et plusieurs autres branchements, rien n’a jusqu’à présent permis d’obtenir une réponse du circuit.

Une âme charitable pourrait-elle m’aider à élaborer un code qui marche s’il vous plait?

Merci d’avance! :slight_smile:

Le fichier "stdio.h" n'est-il pas déjà inclus avec l'IDE?

Chemin d'accès: arduino-1.0.1\hardware\tools\avr\avr\include

stdio.h pas Stdio.h

Avec une minuscule

Bonjour!

Je me sens vraiment bête pour le coup car en effet, l’IDE a enfin accepté de téléverser le programme avec “stdio.h”.
Merci beaucoup!

Par contre, un “petit” problème demeure :
la première fois, le port série ne recevait rien, j’ai donc décidé de re-téléverser le programme mais maintenant j’ai un autre message d’erreur.

processing.app.SerialException: Erreur d'ouverture du port série « /dev/ttyACM0 ».
	at processing.app.Serial.<init>(Serial.java:178)
	at processing.app.Serial.<init>(Serial.java:77)
	at processing.app.debug.Uploader.flushSerialBuffer(Uploader.java:77)
	at processing.app.debug.AvrdudeUploader.uploadViaBootloader(AvrdudeUploader.java:172)
	at processing.app.debug.AvrdudeUploader.uploadUsingPreferences(AvrdudeUploader.java:67)
	at processing.app.Sketch.upload(Sketch.java:1706)
	at processing.app.Sketch.exportApplet(Sketch.java:1662)
	at processing.app.Sketch.exportApplet(Sketch.java:1634)
	at processing.app.Editor$DefaultExportHandler.run(Editor.java:2346)
	at java.lang.Thread.run(Thread.java:724)
Caused by: gnu.io.UnsupportedCommOperationException: Invalid Parameter
	at gnu.io.RXTXPort.setSerialPortParams(RXTXPort.java:213)
	at processing.app.Serial.<init>(Serial.java:163)
	... 9 more
processing.app.debug.RunnerException: Erreur d'ouverture du port série « /dev/ttyACM1 ».
	at processing.app.debug.Uploader.flushSerialBuffer(Uploader.java:101)
	at processing.app.debug.AvrdudeUploader.uploadViaBootloader(AvrdudeUploader.java:172)
	at processing.app.debug.AvrdudeUploader.uploadUsingPreferences(AvrdudeUploader.java:67)
	at processing.app.Sketch.upload(Sketch.java:1706)
	at processing.app.Sketch.exportApplet(Sketch.java:1662)
	at processing.app.Sketch.exportApplet(Sketch.java:1634)
	at processing.app.Editor$DefaultExportHandler.run(Editor.java:2346)
	at java.lang.Thread.run(Thread.java:724)
avrdude: stk500v2_getsync(): timeout communicating with programmer
avrdude: stk500v2_ReceiveMessage(): timeout

Je précise que je suis sous Linux si ça peut avoir une incidence.
Aurais-je grillé le gestionnaire USB de l’arduino ou fait une quelconque connerie similaire?

Au moins maintenant, je sais que le code lui-même marche, et c’est grâce à vous, merci!

Sinon : http://forum.arduino.cc/index.php?topic=33434.0;wap2

Merci pour le lien!

La version corrigée, s'agit-il d'une fonction à intégrer dans le "void loop()" ou d'une portion de code destinée à remplacer la première version? Je ne sais pas si je suis très clair...

Dans le premier cas, faut-il utiliser les mêmes variables qu'au dessus?

Nan c'est une fonction tout court, il te suffit d'y faire appel ensuite dans ton loop

unsigned long Voltage = Mesure();

Après c'est un des premiers code que j'ai fait, il mériterait quelques optimisations xD mais il est fonctionnel !

Merci!

J’ai juste un dernier petit problème concernant le transfert (le même que tout à l’heure en fait) :

Taille binaire du croquis : 6 162 octets (d'un max de 258 048 octets)
processing.app.SerialException: Erreur d'ouverture du port série « /dev/ttyACM0 ».
	at processing.app.Serial.<init>(Serial.java:178)
	at processing.app.Serial.<init>(Serial.java:77)
	at processing.app.debug.Uploader.flushSerialBuffer(Uploader.java:77)
	at processing.app.debug.AvrdudeUploader.uploadViaBootloader(AvrdudeUploader.java:172)
	at processing.app.debug.AvrdudeUploader.uploadUsingPreferences(AvrdudeUploader.java:67)
	at processing.app.Sketch.upload(Sketch.java:1706)
	at processing.app.Sketch.exportApplet(Sketch.java:1662)
	at processing.app.Sketch.exportApplet(Sketch.java:1634)
	at processing.app.Editor$DefaultExportHandler.run(Editor.java:2346)
	at java.lang.Thread.run(Thread.java:724)
Caused by: gnu.io.UnsupportedCommOperationException: Invalid Parameter
	at gnu.io.RXTXPort.setSerialPortParams(RXTXPort.java:213)
	at processing.app.Serial.<init>(Serial.java:163)
	... 9 more
processing.app.debug.RunnerException: Erreur d'ouverture du port série « /dev/ttyACM0 ».
	at processing.app.debug.Uploader.flushSerialBuffer(Uploader.java:101)
	at processing.app.debug.AvrdudeUploader.uploadViaBootloader(AvrdudeUploader.java:172)
	at processing.app.debug.AvrdudeUploader.uploadUsingPreferences(AvrdudeUploader.java:67)
	at processing.app.Sketch.upload(Sketch.java:1706)
	at processing.app.Sketch.exportApplet(Sketch.java:1662)
	at processing.app.Sketch.exportApplet(Sketch.java:1634)
	at processing.app.Editor$DefaultExportHandler.run(Editor.java:2346)
	at java.lang.Thread.run(Thread.java:724)

Je suis chiant je sais, désolé, ça fait un moment que j’ai pas utilisé un arduino, j’ai un peu perdu la main…

Merci à tous de votre aide. Pour une fois, je vais attaquer le lundi de bonne humeur! :slight_smile:

Erreur d'ouverture du port série « /dev/ttyACM0 »

De toute évidence, le port série ne s'installe pas correctement Ou bien il est vérouillé par une autre app

Quand tu branches ton Arduino, puis que tu tape "dmesg" Que vois tu concernant l'USB ou le port série ? (c'est quoi comme modèle de carte Arduino)

J'ai une carte Arduino Mega 2560 Rev3.

Tout ce qui semble concerne la carte est ici :

[  995.269672] usb 1-1.1: new full-speed USB device number 3 using ehci_hcd
[  995.364806] usb 1-1.1: New USB device found, idVendor=2341, idProduct=0042
[  995.364814] usb 1-1.1: New USB device strings: Mfr=1, Product=2, SerialNumber=220
[  995.364819] usb 1-1.1: Manufacturer: Arduino (www.arduino.cc)
[  995.364823] usb 1-1.1: SerialNumber: A4139373530351516222
[  995.424588] cdc_acm 1-1.1:1.0: ttyACM0: USB ACM device
[  995.425174] usbcore: registered new interface driver cdc_acm
[  995.425176] cdc_acm: USB Abstract Control Model driver for USB modems and ISDN adapters
[ 1218.176377] usb 1-1.1: USB disconnect, device number 3

NB : plus bas dans les résultats, on trouve la même chose commençant par "[ 4254.661001] usb 1-1.2". Au fil des essais, j'ai eu l'impression que le port était considéré comme "double", comme s'il croyait qu'il était relié à plusieurs arduinos.

I used this code as starting point for 1602 serial display. The code is the same as the code from Martin Nawrath which is all over internet.

I just searched the web for the first stdio.h I could find, and the code compiled OK. You should use the latest version from the eBay seller link (only one seller, and one link). It was very easy to make the code run and convert to cheap 1602 I2C and Nokia 5110 SPI displays from eBay.

http://www.youtube.com/watch?v=-SqULFoQzks

http://www.eevblog.com/forum/projects/ppmgeek!-5-5-digit-dvm-volt-ref-cal-%28for-arduino-or-any-uc-w-spi%29/