Forum: Compiler & IDEs String Konvertierung


von Dani_Boy (Gast)


Lesenswert?

Hallo liebe Experten,
ich bin ein Anfänger in der C Programmierung und arbeite mich im Rahmen 
eines kleinen Projktes in die Thematik ein.
Ich bin gerade dabei ein Mikro auszulesen. Den ADC habe ich konfiguiert- 
Ich denke das passt soweit auch. Wenn ich nun den ADC Wert auf dem LCD 
ausgeben will habe ich ein Problem: Es werden zeichen angezeigt. Wenn es 
laut ist verändern sich die zeichen, wenn es still ist sind die zeichen 
konstant. DAs heißt es wird definitiv etwas erkannt nur die Ausgabe 
erfolgt im Falschen Format (Smylies? Krytisch?).
Ich habe über itoa versucht den integer zu einem String zu wandeln, aber 
es funktioniert nicht (Nun sind es Zahlen. Die hintere Zahl verändert 
sich in Abhängikeit der Lautstärke). Letztendlich erhoffe ich mir einen 
wert zwischen zwischen 0-255 welcher für die Lautstärke steht.

ch habe auch schon mit der sprintf Funktion etwas probiert jedoch ohne 
erfolg.

Falls einer eine Idee habt, wäre ich für jede Hilfe dankbar.

Grüße und Danke

Daniel
1
#ifndef F_CPU
2
  #define F_CPU 1000000UL
3
#endif
4
5
6
7
#include <avr/io.h>
8
#include <avr/interrupt.h>
9
#include <stdint.h>
10
#include <stdlib.h>
11
#include <util/delay.h>
12
#include <avr/pgmspace.h>
13
14
15
#include "includes/uart.h"
16
#include "includes/lcd.h"
17
#include "includes/twi.h"
18
#include "includes/dataflash.h"
19
 
20
//Funktionen
21
void adc_read(void);
22
void adc_Init(void); 
23
24
//Globale Variablen
25
uint8_t akt_db[7];
26
uint16_t ad_in[32];
27
char buf[6];
28
29
30
31
int main (void)
32
{
33
  LCD_Init();
34
  adc_Init();
35
  adc_read();
36
 
37
38
  while(1)
39
  {
40
  itoa(ADC,buf,10);
41
  LCD_PutString(buf);
42
  LCD_Update();  
43
  }
44
}
45
46
void adc_Init(void)
47
{
48
  PORTA &= ~(1<<PORTA0);
49
  DDRA = 0x02;            //PORTA als Eingäng definiert
50
  ADMUX |= (1<<REFS0);          //Referenz auf AVCC
51
  ADCSRB = 0x00;            //Free running mode
52
  ADCSRA |= (1<<ADEN)|(1<<ADATE)|(1<<ADSC)|(1<<ADPS2)|(1<<ADPS1);    //Startet ADC, Auto-Trigger Source, Starten der Umwandlung
53
}
54
55
void adc_read(void)
56
{
57
  for (uint8_t i = 0; i < 32; i++)
58
  {
59
    while (!(ADCSRA & (1<<ADIF)))      //Warte auf neue Daten
60
    {
61
    }
62
    ad_in[i] = ADC;          //Übergabe der 10bit-Zahl
63
    ADCSRA |= (1 << ADIF);        //Flag löschen
64
  }
65
}

von Rolf M. (rmagnus)


Lesenswert?

Dani_Boy schrieb:
> Ich habe über itoa versucht den integer zu einem String zu wandeln, aber
> es funktioniert nicht (Nun sind es Zahlen. Die hintere Zahl verändert
> sich in Abhängikeit der Lautstärke). Letztendlich erhoffe ich mir einen
> wert zwischen zwischen 0-255 welcher für die Lautstärke steht.

Bringt denn der Ausgang deines Mikrofons überhaupt Spannungen im Bereich 
0 bis AVCC raus?

> Smylies? Krytisch?

Äh, was?

von W.S. (Gast)


Lesenswert?

Versuche doch erst einmal, die einzelnen Programmteile separat in Gang 
zu kriegen.

Insbesondere all diese Funktionen wie itoa, printf und Konsorten sind 
erstens für deine Anwendung völlig überdimensioniert und zweitens mit 
einigen Haken und Ösen versehen.

Fang also mal ganz klein an z.B. mit

volatile int a;

 a = 0x31;
 buf[5] = 0;
 buf[4] = 'z';
 buf[3] = 'y';
 buf[2] = a;
 buf[1] = a+2-buf[5];
 buf[0] = '9';
 LCD_PutString(buf);
 LCD_Update();

Mit sowas kannst du erstmal testen, ob überhaupt am Display das ankommt, 
was du dir gedacht hast - ohne daß ein oberschlauer Compiler dir die 
Hälfte wegoptimiert.

Dann kannst du weitermachen mit sowas wie
 a = 123;
 itoa(a, .....)
und so weiter, um danach dein itoa auszuprobieren.

Danach erst ist der ADC dran.

W.S.

von Karl H. (kbuchegg)


Lesenswert?

W.S. schrieb:

> Mit sowas kannst du erstmal testen, ob überhaupt am Display das ankommt,
> was du dir gedacht hast

Grundsätzlich bin ich deiner Meinung.

Wenn die LCD Ausgabe das Problem ist, dann sollte man die erst mal für 
sich alleine testen.

Aber ein
1
...
2
3
int main (void)
4
{
5
  LCD_Init();
6
7
  while(1)
8
  {
9
    LCD_PutString( "Hallo" );
10
    LCD_Update();  
11
  }
12
}

sollte es für die ersten Tests auch tun.
Wenn da am LCD schon nicht "Hallo" steht, dann braucht man mit ADC 
und/oder itoa erst mal gar nicht weiter machen sondern muss den Fehler 
in den LCD Routinen suchen.

von Dani_Boy (Gast)


Lesenswert?

Hallo Leute,
danke für die Antworten.
Also mit der Funktion LCD_PutString (); kann ich alles auf dem Display 
anzeigen. Sämtliche Strings. Auch Hintergrundbeleuchtungen ändern, 
Kreise und Balken erstllen funktioniert alles über die entsprechende 
bib. Ich denke hinsichltich der Ausgabe passt das.
Ich vermute das mit LCD_PutString (); der LCD ein String erwartet dieser 
aber über itoa nicht korrekt zur Verfügung gestellt wird und der LCD 
dies falsch interpretiert?! Daraus resultieren irgendwelche komischen 
Zeichenketten.
Ich verstehe nur nicht wie ich den Wert aus ADC auf dem LCD ausgegeben 
bekomme.
Ich werde die Möglichkeit von W.S. morgen früh einmal testen und schauen 
was bei mir raus kommt.

Danke soweit schon einmal.

Falls noch jemand eine Idee hat, ich bin über jeden Input sehr dankbar.

Grüße und einen schönen Abend

Daniel

von Joe F. (easylife)


Lesenswert?

Also mal abgesehen davon, dass ich dein Programm nicht verstehe (zuerst 
liest du 32 ADC Werte in ein Array, und dann gehst du in eine 
Endlosschleife und zeigst immer wieder das selbe an...? Das Array mit 
den Messwerten taucht aber beim Anzeigen nirgendwo auf...) heisst die 
Funktion die du suchst in der Tat "sprintf".
1
char buf[20];
2
int x=531;
3
sprintf(buf, "%d", x);
4
LCD_PutString(buf);
5
LCD_Update();

: Bearbeitet durch User
von Dani_Boy (Gast)


Lesenswert?

Hi Joe F.,
danke für die Hilfe.
Ich habe gerade ein Verständnisproblem.
1)
1
 uint16_t ad_in [32]
 ist ein Array in das ich meine 32 Werte Werte  schreibe. Wie bekomme 
ich dieses Array auf dem LCD ausgegeben? Kann ich das komplett zu einem 
String konvertieren?
2) Das Array ist primär für spätere Anwendungen relevant wichtiger wäre 
es mir erstmal nur den aktullen ADC Wert azuszugebem
1
 ADC
. Das habe ich wie oben bereits beschrieben über:
1
char buf [4],
2
itoa [ADC,buf,10]
probiert aber ohne erfolg.

Mein akueller Code sieht so aus. Im vorliegenden Fall habe ich es mit 
der sprintf Variante versucht das
1
 ad_in
 array auszugeben. Leider bekomme ich nur eine Lange Zahlenkette raus.
1
#ifndef F_CPU
2
  #define F_CPU 1000000UL
3
#endif
4
5
6
7
#include <avr/io.h>
8
#include <avr/interrupt.h>
9
#include <stdint.h>
10
#include <stdlib.h>
11
#include <util/delay.h>
12
#include <avr/pgmspace.h>
13
14
15
#include "includes/uart.h"
16
#include "includes/lcd.h"
17
#include "includes/twi.h"
18
#include "includes/dataflash.h"
19
 
20
//Funktionen
21
void adc_read(void);
22
void adc_Init(void);
23
void adc_ausgabe(void);
24
25
//Globale Variablen
26
uint16_t ad_in[32];
27
char buf[20];
28
29
30
31
32
int main (void)
33
{
34
  LCD_Init();
35
  adc_Init();
36
  adc_read();
37
38
  
39
 
40
41
  while(1)
42
  {
43
  
44
  adc_ausgabe();
45
  }
46
47
}
48
49
void adc_Init(void)
50
{
51
  PORTA &= ~(1<<PORTA0);
52
  DDRA = 0x02;            //PORTA als Eingäng definiert
53
  ADMUX |= (1<<REFS0);          //Referenz auf AVCC
54
  ADCSRB = 0x00;            //Free running mode
55
  ADCSRA |= (1<<ADEN)|(1<<ADATE)|(1<<ADSC)|(1<<ADPS2)|(1<<ADPS1);    //Startet ADC, Auto-Trigger Source, Starten der Umwandlung
56
}
57
58
void adc_read(void)
59
{
60
  for (uint8_t i = 0; i < 32; i++)
61
  {
62
    while (!(ADCSRA & (1<<ADIF)))      //Warte auf neue Daten
63
    {
64
    }
65
    ad_in[i] = ADC;          //Übergabe der 10bit-Zahl
66
    ADCSRA |= (1 << ADIF);        //Flag löschen
67
  }
68
}
69
70
void adc_ausgabe (void) 
71
{
72
  sprintf(buf, "%d", ad_in);
73
        LCD_PutString(buf);
74
  LCD_Update();
75
  
76
}

Falls einer zu Problem 1) oder 2) eine Idee oder Bemerkung hat bin ich 
wirklich dankbar.
Wie gesagt ich bin Anfänger und lese mich gerade etwas in Thematik ein, 
falls eins zwei Antworten trivial erscheinen, seit mir nich böse.

Grüße
Daniel

von Fritz G. (fritzg)


Lesenswert?

Dani_Boy schrieb:
> sprintf(buf, "%d", ad_in);

Der Befehl gibt eine lange Zahlenkette aus. Und zwar so schnell es geht, 
wahrscheinlich ein paar Tausend Zahlen pro Sekunde.
"%d " gibt dir wenigstens ein Leerzeichen hinter jeder Zahl aus, ein 
Delay von z.B. einer Sekunde trägt einiges zur Lesbarkeit bei.

von Frank M. (ukw) (Moderator) Benutzerseite


Lesenswert?

Dani_Boy schrieb:
> habe ich wie oben bereits beschrieben über:
>
1
> char buf [4],
2
> itoa [ADC,buf,10]
3
>
> probiert aber ohne erfolg.

Die Parameter von Funktionen wie itoa packt man in runde Klammern. Der 
Buffer sollte so groß sein, dass er den Maximalwert plus die nötige 
Terminierung mit '\0' aufnehmen kann.

Solche Sachen kann man systematisch lernen, denn man findet sie in jedem 
guten C-Buch. Ist einfach besser als das Trial-and-Error-System, wo man 
sich alle paar Minuten platt auf die Nase legt - ganz zu schweigen von 
den Fehlern, die man aus Unwissenheit reinbaut, welche sich dann erst 
nach Jahren rächen...

von Joe F. (easylife)


Lesenswert?

1
sprintf(buf, "%d %d %d %d", ad_in[0], ad_in[1], ad_in[2], ad_in[3]);

konvertiert dir die ersten 4 Werte des Arrays in einen String.
Wie es mit 32 Werten ginge, kannst du dir denken.

"ad_in" ist in C die Speicher-Adresse des ersten Arrayeintrages 
"ad_in[0]"

von Eric (Gast)


Lesenswert?

Du übergibst sprintf das ganze Array; sprintf benötigt aber nur ein 
einzigen Wert. Ausserdem liest du den ADC nur einmal, nämlich bevor 
deine Endlosschleife loslegt. Danach werden sich die Werte im Array 
nicht mehr ändern.

Mach mal das Auslesen des ADCs innerhalb der Schleife und lass' das 
Array aus.
1
int main()
2
{
3
  uint16_t adcval;
4
5
  LCD_Init();
6
  adc_Init();
7
8
  while(1)
9
  {
10
    // Read ADC
11
    while (!(ADCSRA & (1<<ADIF)))      //Warte auf neue Daten
12
    {
13
    }
14
    adcval = ADC;
15
16
    // Output ADC
17
    sprintf(buf, "%d", adcval);
18
    LCD_PutString(buf);
19
    LCD_Update();
20
  }
21
}

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
Noch kein Account? Hier anmelden.