Forum: Mikrocontroller und Digitale Elektronik Ausgabe der AD-Wandlung


von Flo (Gast)


Lesenswert?

hallo zusammen!
analoge signale sollen mit meinem uc digitalisiert werden. nach dem 
einlesen aller geforderten daten will ich das ergebnis sehen. leider ist 
die ausgabe nicht gleichbleibend - z.b. lese ich zwei sensoren ein ist 
s1 an der 1. und s2 an der 2. stelle im array; lese ich nur s1 ein, dann 
ist das ergebnis an der 2. stelle. was mache ich falsch?

codeauszüge:

// die variablen
int Sensor_Nummer;
int Werte[8] = {0,0,0,0,0,0,0,0};

// auslesen
switch( Sensor_Nummer )
{
case 1:
read_adc(0);
Werte[1] = ADCW;
break;

case 2:
read_adc(1);
Werte[2] = ADCW;
break;

case 3:
read_adc(2);
Werte[3] = ADCW;
break;

case 4:
read_adc(3);
Werte[4] = ADCW;
break;

case 5:
read_adc(4);
Werte[5] = ADCW;
break;

case 6:
read_adc(5);
Werte[6] = ADCW;
break;

case 7:
read_adc(6);
Werte[7] = ADCW;
break;

case 8:
read_adc(7);
Werte[8] = ADCW;
break;
}

// ausgabe und werte wieder auf null setzen
stdout = &mystdout;
printf(" Werte: %u, %u, %u, %u, %u, %u, %u, %u 
\n",Werte[1],Werte[2],Werte[3],Werte[4],Werte[5],Werte[6],Werte[7],Werte 
[8]);

Werte[1] = 0;
Werte[2] = 0;
Werte[3] = 0;
Werte[4] = 0;
Werte[5] = 0;
Werte[6] = 0;
Werte[7] = 0;
Werte[8] = 0;

schon mal vielen dank für eure unterstützung.
gruß
 der Flo

von Karl H. (kbuchegg)


Lesenswert?

int Werte[8] = {0,0,0,0,0,0,0,0};
...

Werte[8] = ADCW;

Autsch.
In C wird bei 0 angefangen zu zählen. Ein Array mit 8 Elementen,
so wie hier
  int Werte[8] = {0,0,0,0,0,0,0,0};

besitzt also die Indizes:

   0, 1, 2, 3, 4, 5, 6, 7

(zähl nach. Es sind genau 8 Stück).

Ein Werte[8] existiert nicht! Du weist hier den Wert
irgendwohin zu und überschreibst dir damit wer weis was.


Aber warum so kompliziert mit einem switch-case? Deine
Fälle sind alle gleich, nur ein paar Zahenwerte ändern sich:

// auslesen
  read_adc( Sensor_Nummer - 1 );
  Werte[ Sensor_Nummer - 1] = ADCW;

macht genau das gleiche, wie dein 20 Zeilen switch-case Konstrukt
von oben.

von johnny.m (Gast)


Lesenswert?

Wenn Du ein Array mit
1
int Werte[8] = {0,0,0,0,0,0,0,0};
anlegst, dann ist das ein Array mit 8 Werten, die bei 0 beginnend 
indiziert werden. Der Wert "Werte[8]" existiert in dem Array gar nicht! 
Der höchste Wert ist "Werte[7]"... Und da Du den Wert von Deinem ersten 
Sensor an der Stelle Werte[1] speicherst, ist es klar, dass beim 
Auslesen des Arrays Mist rauskommt. Am besten nummerierst Du Deine 
Sensoren von 0 an (wie man es in der Elektronik/Digitaltechnik 
eigentlich immer macht) und speicherst den ersten Wert (also den von 
Sensor 0) auch in "Werte[0]". Was beim Auslesen von "Werte[8]" 
rauskommt, ist undefiniert.

von Flo (Gast)


Lesenswert?

ist mir ja richtig peinlich....

vielen dank!

vor einiger zeit gab es mal einen betrag in dem der aufbau einer 
statemachine beschrieben wurde. wollte diesen ansatz kopieren doch ich 
kann meinen fehler nicht genau lokalisieren.

anbei der auszug:

while(1)
{

uart_gets(Buffer);

Index = 0;
while( Buffer[Index] != '_' )
  {
    NextChar = Buffer[Index++];

    if( NextChar == ' '  ||  NextChar == '\t'  ||  NextChar == '\n' )
      continue;

    switch( State )
  {
      case START_SENSOR_AUSWAHL:

      if( NextChar >= '0' && NextChar <= '9' )
      {
      Sensor_Nummer = NextChar - '0';

        switch( Sensor_Nummer )
        {
          case 1:
        read_adc(0);
        Werte[0] = ADCW;
        break;

        case 2:
        read_adc(1);
        Werte[1] = ADCW;
        break;

        case 3:
        read_adc(2);
        Werte[2] = ADCW;
        break;

        case 4:
        read_adc(3);
        Werte[3] = ADCW;
        break;

        case 5:
        read_adc(4);
        Werte[4] = ADCW;
        break;

        case 6:
        read_adc(5);
        Werte[5] = ADCW;
        break;

        case 7:
        read_adc(6);
        Werte[6] = ADCW;
        break;

        case 8:
        read_adc(7);
        Werte[7] = ADCW;
        break;
        }
        Sensor_Nummer = 0;
        State = FIND_SEMICOLON;

          }
          else
            State = FIND_SEMICOLON;
          break;

      case FIND_SEMICOLON:
        if( NextChar == ';' )
    {
          State = START_SENSOR_AUSWAHL;
        }
    // Ende vom switch
   }

// Ende vom while(Buffer)
}

stdout = &mystdout;
printf(" Werte: %u, %u, %u, %u, %u, %u, %u, %u 
\n",Werte[0],Werte[1],Werte[2],Werte[3],Werte[4],Werte[5],Werte[6],Werte 
[7]);

Werte[0] = 0;
Werte[1] = 0;
Werte[2] = 0;
Werte[3] = 0;
Werte[4] = 0;
Werte[5] = 0;
Werte[6] = 0;
Werte[7] = 0;

// Ende vom while
}

wenn mich nicht alles täuscht, dann kam die damalige antwort von Karl 
heinz. fand die idee echt klasse.

gruß
  der Flo

von Karl H. (kbuchegg)


Lesenswert?

Kürzen, kürzen, kürzen.

Arrays haben den grossen Vorteil, dass du als Indizierung
einen beliebigen arithmetischen Ausdruck benutzen kannst
solange der errechnete Wert nur in den Arraygrenzen liegt.

Nutze die Macht, Flo!
1
  while(1)
2
  {
3
4
    uart_gets(Buffer);
5
6
    Index = 0;
7
    while( Buffer[Index] != '_' )
8
    {
9
      NextChar = Buffer[Index++];
10
11
      if( NextChar == ' '  ||  NextChar == '\t'  ||  NextChar == '\n' )
12
        continue;
13
14
      switch( State )
15
      {
16
        case START_SENSOR_AUSWAHL:
17
18
          if( NextChar >= '0' && NextChar <= '9' )
19
          {
20
            Sensor_Nummer = NextChar - '0' - 1;
21
            read_adc( Sensor_Nummer );
22
            Werte[Sensor_Nummer] = ADCW;
23
          }
24
          State = FIND_SEMICOLON;
25
          break;
26
27
        case FIND_SEMICOLON:
28
          if( NextChar == ';' )
29
          {
30
            State = START_SENSOR_AUSWAHL;
31
          }
32
      } // Ende vom switch
33
    } // Ende vom while(Buffer)
34
  } // Ende der Endlosschleife

  

von Flo (Gast)


Lesenswert?

leider ist die macht noch nicht ganz auf meiner seite...
die ausgabe hakt! bei spannungsänderungen wird immer nur der zuerst 
gemessene wert angezeigt - änderungen werden nicht registriert.

while(1)
{

uart_gets(Buffer);

Index = 0;
while( Buffer[Index] != '_' )
  {
    NextChar = Buffer[Index++];

    if( NextChar == ' '  ||  NextChar == '\t'  ||  NextChar == '\n' )
      continue;

    switch( State )
  {
      case START_SENSOR_AUSWAHL:

      if( NextChar >= '0' && NextChar <= '9' )
      {
      Sensor_Nummer = NextChar - '1';
      read_adc( Sensor_Nummer );
      Werte[Sensor_Nummer] = ADCW;
      }
          State = FIND_SEMICOLON;
      break;


      case FIND_SEMICOLON:
      if( NextChar == ';' )
        {
          State = START_SENSOR_AUSWAHL;
          Sensor_Nummer = 0;
        }
    // Ende vom switch
   }

// Ende vom while(Buffer)
}

stdout = &mystdout;
printf(" Werte: %u, %u, %u, %u, %u, %u, %u, %u 
\n",Werte[0],Werte[1],Werte[2],Werte[3],Werte[4],Werte[5],Werte[6],Werte 
[7]);

// Ende vom while
}

was mache ich falsch?

gruß
  der Flo

von Rahul, der Trollige (Gast)


Lesenswert?

>Sensor_Nummer = NextChar - '1';

Vorher vergleichst du auf >='0'...

von Flo (Gast)


Lesenswert?

der vergleich soll nur dazu dienen, dass eine numerische eingabe 
ankommt. daher ist dort '0' oder '1' richtig - glaub ich zumindest.

dass mit Sensor_Nummer = ... - '1' muss so sein, da ich zuvor die 
arraystruktur falsch angewendet habe.

von Werner B. (Gast)


Lesenswert?

Vorsichtshalber noch...
1
...
2
while( Buffer[Index] != 0 && Buffer[Index] != '_' )
3
...
da ich (in meinem jugendlichen Leichtsinn) davon ausgehe, dass 
uart_gets(Buffer); das Array mit einem '\0' abschließt.

> ...da ich zuvor die arraystruktur falsch angewendet habe.

Dann prüfe aber auch ob NextChar von '1' bis '8' läuft. '0' und '9' sind 
unzulässig.
Richtiger ist...
1
...
2
if( NextChar > '0' && NextChar < '9' )
3
...

Solche essetiellen Fehler können im Speicher ein echtes Kaos anrichten. 
Kein Wunder wenn nur Müll rauskomt.

von Flo (Gast)


Lesenswert?

du hast recht! die if-abfrage sollte die von dir vorgeschlagene form 
haben - änderung schon eingebaut. doch leider hat sich mein problem 
damit noch nicht gelöst... die werte werden erst nach einem reset 
richtig eingelesen und dann halt auch nur ein mal.

von Karl H. (kbuchegg)


Lesenswert?

Dann musst du mal deine read_adc Funktion durchforsten.
Was mir etwas komisch vorkommt, ist dass du zwar eine
Funktion namens read_adc hast, den Messwert aber trotzdem
direkt aus dem ADCW Register holst.
Von einer Funktion, die read_adc heist, würde ich erwarten,
dass sie mir den Messwert direkt zurückliefert. Das
ich sie also so anwenden kann:

   Wert[Sensor_Nummer] = read_adc( Sensor_Nummer );

Das aber nur nebenbei. Denn ob du den ADC Wert nach
dem Funktionsaufruf holst, oder ob die letzte Aktion
in read_adc ein
   return ADCW;

ist, ist für das gegenständliche Problem (der Messwert
wird nicht gelesen) unerheblich. Da musst du dir die
read_adc() Funktion anschauen.

von Flo (Gast)


Lesenswert?

du hast natürlich recht...

die funktion sieht so aus - hat bisher eigentlich auch immer geklappt!

#define ADC_VREF_TYPE 0x40

unsigned int read_adc(unsigned char adc_input)
{
  ADMUX=adc_input|ADC_VREF_TYPE;
  ADCSRA|=0x40;
  while ((ADCSRA & 0x10)==0)
    ;
  ADCSRA|=0x10;
  return ADCW;
}

denke, es liegt an der schleife. lasse jetzt die gültige nummer 
ausgeben, und auch hier hakt die sache. bei einer abfrage von zwei 
sensoren, wird z.b. nur einer ausgelesen.

// Endlosschleife
while(1)
{

uart_gets(Buffer);

Index = 0;
while( Buffer[Index] != '_' )
  {
    NextChar = Buffer[Index++];

    if( NextChar == ' '  ||  NextChar == '\t'  ||  NextChar == '\n' )
      continue;

    switch( State )
  {
      case START_SENSOR_AUSWAHL:

    if( NextChar > '0' && NextChar < '9' )
    {
    Sensor_Nummer = NextChar - '1';
    Werte[Sensor_Nummer] = read_adc( Sensor_Nummer );
    stdout = &mystdout;
    printf(" Sensor_Nummer: %u", Sensor_Nummer);
    printf(" Test %u",Werte[Sensor_Nummer]);
    }
          State = FIND_SEMICOLON;
    break;


      case FIND_SEMICOLON:
        if( NextChar == ';' )
  {
          State = START_SENSOR_AUSWAHL;
        }
    // Ende vom switch
   }

// Ende vom while(Buffer)
}

stdout = &mystdout;
printf(" Werte: %u, %u, %u, %u, %u, %u, %u, %u 
\n",Werte[0],Werte[1],Werte[2],Werte[3],Werte[4],Werte[5],Werte[6],Werte 
[7]);


// Ende vom while
}


sorry für die kryptische darstellung... füge immer kopierten code ein...

gruß
  Flo

von Flo (Gast)


Lesenswert?

vielleicht ist ja auch mein uc kaputt...
zuerst gehe ich aber immer von fehlern in meinem code aus ;-)
wenn jemand diesen - siehe letzten beitrag - testen könnte, wäre ich 
sehr dankbar.

gruß
  Flo

von Rahul, der Trollige (Gast)


Lesenswert?

>sorry für die kryptische darstellung... füge immer kopierten code ein...

Wenn du da vor ein
1
 und dahinter ein
 setzt, wird es auch noch hübsch.

Du solltest mal über die serielle ausgeben, dass der Befehl richtig 
empfangen wurde. Das wäre ein Test für die Statemachine.

von Rahul, der Trollige (Gast)


Lesenswert?

ich bin sooooooo doof!

es muß natürlich [ c ] und [ / c ] heissen (ohne Leerzeichen...)

von Karl H. (kbuchegg)


Lesenswert?

Rahul hat recht.
Bau doch mal ein paar printf ein, damit du siehst was
überhaupt passiert:
1
// Endlosschleife
2
3
  stdout = &mystdout;
4
5
  while(1)
6
  {
7
8
    uart_gets(Buffer);
9
    printf( "%s\n", Buffer );
10
11
    Index = 0;
12
    while( Buffer[Index] != '_' )
13
    {
14
      NextChar = Buffer[Index++];
15
16
      if( NextChar == ' '  ||  NextChar == '\t'  ||  NextChar == '\n' )
17
        continue;
18
19
      printf( "Naechstes Zeichen: %c\n", NextChar );
20
21
      switch( State )
22
      {
23
        case START_SENSOR_AUSWAHL:
24
          printf( "Im Status SENSOR_AUSWAHL\n" );
25
26
          if( NextChar > '0' && NextChar < '9' )
27
          {
28
            Sensor_Nummer = NextChar - '1';
29
            Werte[Sensor_Nummer] = read_adc( Sensor_Nummer );
30
            printf(" Sensor_Nummer: %u", Sensor_Nummer);
31
            printf(" Test %u",Werte[Sensor_Nummer]);
32
          }
33
          State = FIND_SEMICOLON;
34
          break;
35
36
        case FIND_SEMICOLON:
37
          printf( "Im Status FIND_SEMICOLON\n" );
38
          if( NextChar == ';' )
39
          {
40
            State = START_SENSOR_AUSWAHL;
41
          }
42
        // Ende vom switch
43
      }
44
45
     // Ende vom while(Buffer)
46
    }

Jetzt sagt dir das Programm was es tut und warum es das tut.
Daraus kannst du dann deine Schlüsse ziehen.

In welchem Status beginnt die Sate Maschine eigentlich?

von Flo (Gast)


Lesenswert?

ich werde das gleich testen, nachdem ich einen neuen uc organisiert 
habe... hab gerade mal einzelne sensoren eingelesen und die ad-wandlung 
springt (delta von 100 bei einer auflösung von 10bit) oder der port 
reagiert gar nicht mehr. wie hab ich das denn geschafft?

der automat startet in: State = START_SENSOR_AUSWAHL;

bis demnächst
  Flo

von Flo (Gast)


Lesenswert?

ich glaub ich bin echt zu blöd. es will nicht so, wie ich es gern hätte. 
vielleicht solte ich es sein lassen....

jetzt mal mein vollständiger code
1
#include <avr/io.h>
2
#include <stdio.h>
3
#include <string.h>
4
5
#define START_SENSOR_AUSWAHL  0
6
#define FIND_SEMICOLON        1    
7
8
int State =0;
9
int Index;
10
int Sensor_Nummer;
11
int Werte[8] = {0,0,0,0,0,0,0,0};
12
13
char NextChar;
14
char Buffer[40];
15
16
17
18
static int uart_putchar(char c, FILE *stream);
19
static FILE mystdout = FDEV_SETUP_STREAM(uart_putchar, NULL,
20
                                             _FDEV_SETUP_WRITE);
21
22
static int
23
    uart_putchar(char c, FILE *stream)
24
    {
25
26
      if (c == '\n')
27
        uart_putchar('\r', stream);
28
      loop_until_bit_is_set(UCSRA, UDRE);
29
      UDR = c;
30
      return 0;
31
    }
32
33
34
35
void uart_putc( char c )
36
{
37
  // Warte bis die Sendeeinheit bereit ist
38
  while( !(UCSRA & ( 1<<UDRE) ) )
39
    ;
40
  UDR = c;
41
}
42
43
44
45
void uart_puts( const char* str )
46
{
47
  while( *str ) 
48
  {
49
    uart_putc( *str );
50
    str++;
51
  }
52
}
53
54
55
unsigned char USART_RX(void)
56
{
57
  while(!(UCSRA&(1<<RXC)))
58
    ;
59
  return UDR;
60
}
61
62
63
void uart_gets( char* Input )
64
{
65
  char c = USART_RX();
66
67
  while( c != '_' ) 
68
  {
69
    *Input = c;
70
    Input++;
71
    c = USART_RX();
72
  }
73
  *Input = '\0';
74
}
75
76
77
void uart_init(void)
78
{
79
  // USART Baud rate: 19.200 bps
80
  UBRRH = 0x00;  
81
  UBRRL = 0x0B;
82
  UCSRA = 0x00;
83
  UCSRB = 0x18;
84
  UCSRC = 0x86;
85
}
86
87
88
#define ADC_VREF_TYPE 0x40
89
90
unsigned int read_adc(unsigned char adc_input)
91
{
92
  ADMUX=adc_input|ADC_VREF_TYPE;
93
  ADCSRA|=0x40;
94
  while ((ADCSRA & 0x10)==0)
95
    ;
96
  ADCSRA|=0x10;
97
  return ADCW;
98
}
99
100
int main(void)
101
{
102
ADMUX=ADC_VREF_TYPE;
103
ADCSRA=0xA5;
104
SFIOR&=0x1F;
105
106
uart_init();
107
108
// Endlosschleife
109
while(1)
110
 {
111
 
112
uart_gets(Buffer);
113
printf( "%s\n", Buffer );
114
115
Index = 0;
116
while( Buffer[Index] != '#' )
117
{
118
   NextChar = Buffer[Index++];
119
120
   if( NextChar == ' '  ||  NextChar == '\t'  ||  NextChar == '\n' )
121
     continue;
122
123
   printf( "Naechstes Zeichen: %c\n", NextChar );
124
125
   switch( State )
126
     {
127
        case START_SENSOR_AUSWAHL:
128
          printf( "Im Status SENSOR_AUSWAHL\n" );
129
130
          if( NextChar > '0' && NextChar < '9' )
131
          {
132
            Sensor_Nummer = NextChar - '1';
133
            Werte[Sensor_Nummer] = read_adc( Sensor_Nummer );
134
            printf(" Sensor: %c", NextChar);
135
            printf(" Test %u",Werte[Sensor_Nummer]);
136
          }
137
          State = FIND_SEMICOLON;
138
          break;
139
140
        case FIND_SEMICOLON:
141
          printf( "Im Status FIND_SEMICOLON\n" );
142
          if( NextChar == ';' )
143
          {
144
            State = START_SENSOR_AUSWAHL;
145
      Sensor_Nummer = 0;
146
          }
147
        // Ende vom switch
148
      }
149
150
     // Ende vom while(Buffer)
151
    }
152
153
154
stdout = &mystdout;
155
printf(" Werte: %u, %u, %u, %u, %u, %u, %u, %u \n",Werte[0],Werte[1],Werte[2],Werte[3],Werte[4],Werte[5],Werte[6],Werte[7]);
156
157
158
// Ende vom while
159
}
160
// Ende der main
161
}

die eingabe sieht so aus:
sensor 1       ->  ";1#_"
sensor 2       ->  ";2#_"
sensor 1 u. 2  ->  ";1;2#"
etc.

probleme:
- die erste rückgabe ignoriert die zweite while-schleife.
- bei zwei sensoren sind die positionen im array getauscht.

ich weiß nicht mehr weiter...

der müde Flo

von Rahul, der Trollige (Gast)


Lesenswert?

Könntest du vielleicht noch ein UART-Log liefern?

von Flo (Gast)


Lesenswert?

was meinst du damit?

von Rahul, der Trollige (Gast)


Lesenswert?

>State = START_SENSOR_AUSWAHL;

Ersetz das als Startwert mal durch:
State = FIND_SEMICOLON;

Oder fängt dein Protokoll nicht mit einem ";" an?

von Rahul, der Trollige (Gast)


Lesenswert?

>Könntest du vielleicht noch ein UART-Log liefern?

Die Kommunikation zwischen PC und µC, wie du sie im Terminal-Fenster 
siehst.

von Flo (Gast)


Lesenswert?

ein sensor:

eingabe:
;1#_

ausgabe
Werte: 0, 0, 0, 0, 0, 0, 0, 0

eingabe:
;1#_

ausgabe
;1#
Naechstes Zeichen: ;
Im Status FIND_SEMICOLON
Naechstes Zeichen: 1
Im Status SENSOR_AUSWAHL
Sensor: 1 Test 0 Werte: 0, 0, 0, 0, 0, 0, 0, 0

änderungen werden registriert!

zwei sensoren (nach einem reset):

eingabe:
;1;2#_

ausgabe:
Werte: 0, 256, 0, 0, 0, 0, 0, 0   // richtige spannungen!

eingabe:
;1;2#_

ausgabe:
1;2#<\r>
Naechstes Zeichen: ;
Im Status FIND_SEMICOLON
Naechstes Zeichen: 1
Im Status SENSOR_AUSWAHL
Sensor: 1 Test 256Naechstes Zeichen: ;
Im Status FIND_SEMICOLON
Naechstes Zeichen: 2
Im Status SENSOR_AUSWAHL
Sensor: 2 Test 0 Werte: 256, 0, 0, 0, 0, 0, 0, 0

änderungen werden registriert!

so sieht es also aus.

von Rahul, der Trollige (Gast)


Lesenswert?

>eingabe:
>;1#_
>
>ausgabe
>Werte: 0, 0, 0, 0, 0, 0, 0, 0
Da hakt doch deine Statemachine.


gib doch mal ";;1#_" ein. (Gibt es eigentlich einen sinnvollen Grund für 
dieses "bekloppte" Protokoll?)

Ersetz das als State-Startwert mal durch:
State = FIND_SEMICOLON;

von Flo (Gast)


Lesenswert?

>>eingabe:
>>;1#_
>>
>>ausgabe
>>Werte: 0, 0, 0, 0, 0, 0, 0, 0

>Da hakt doch deine Statemachine.

dem ist nicht so!
war vielleicht nicht das beste beispiel. in meinen beispielfällen war 
sensor1 auf 0 V und sensor2 auf 1,2 V.

warum das so aussieht? ich brauchte ein protokoll. wollte den anwender 
die wahl der sensorenselektion überlassen, und der uc wandelt dann die 
geforderten (und auch nur die) analogen signale aus. sensor 1 sitzt pa0, 
sensor 2 sitzt pa1, sensor 3 sitzt pa2, u.s.w. (max. 8 sensoren). hab im 
forum ein bischen nachgelesen und wollte die statemachine 
ausprobieren...

von Rahul, der Trollige (Gast)


Lesenswert?

>war vielleicht nicht das beste beispiel

Würde ich auch sagen.
Poste doch einfach mal einen Ablauf, wie es nicht sein sollte (und 
benutze Werte, die sich auch von dem unterscheiden, was vor der 
Manipulation im Speicher stand).

Meiner Meinung nach solltennämlich immer die Meldung der Stati kommen.
Wenn sie ausbleiben, hängt die Statemachine irgendwo. Pack mal das 
"printf( "Naechstes Zeichen: %c\n", NextChar );" vor die If-Abfrage mit 
"continue".

von Rahul, der Trollige (Gast)


Lesenswert?

Noch was: Soll die Eingabe von Menschen gemacht werden?

von Flo (Gast)


Lesenswert?

danke für deine geduld!

also sensor1 = 1V und sensor2 = 3,6V

nach einem reset

erste eingabe:
;1;2#_

erste ausgabe:
Werte: 214, 214, 0, 0, 0, 0, 0, 0 // das soll schon mal nicht sein. wo
                                  // bleibt die zweite schleife?

zweite eingabe:
;1;2#_

zweite ausgabe:
;1;2#
Naechstes Zeichen: ;<\r>
Im Status FIND_SEMICOLON<\r>
Naechstes Zeichen: 1<\r>
Im Status SENSOR_AUSWAHL<\r>
Sensor: 1 Test 741 <\r>            // das ist nicht richtig
Naechstes Zeichen: ;<\r>
Im Status FIND_SEMICOLON<\r>
Naechstes Zeichen: 2<\r>
Im Status SENSOR_AUSWAHL<\r>
Sensor: 2 Test 214 <\r>            // das auch nicht
Werte: 741, 214, 0, 0, 0, 0, 0, 0  // sensoren sind im array vertauscht


lese ich jeweils einen sensor ein, dann steht das ergebnis an der 
richtigen stelle - leider auch hier fehlt bei der ersten ausgabe die 
zweite schleife.

die eingaben werden von menschen gemacht. allerdings hab ich eine 
oberfläche, in der ich nur einen haken mache. im hintergrund wird der 
string in die gezeigt form gebracht.

von Rahul, der Trollige (Gast)


Lesenswert?

Hast du den "Eröffnungsstate" inzwischen geändert?

>erste ausgabe:
>Werte: 214, 214, 0, 0, 0, 0, 0, 0 // das soll schon mal nicht sein. wo
>                                  // bleibt die zweite schleife?

Nicht nur, dass die Schleife fehlt, es steht auch noch der falsche Wert 
an einer der beiden Stellen. (ich gehe mal von 10Bit und Uref = 5V aus)
Eigentlich müsste da

Werte: 204, 736, 0, 0, 0, 0, 0, 0

stehen.

von Flo (Gast)


Lesenswert?

alles noch so wie zuvor gepostet!
nur das eine endezeichen ist eine raute geworden....

von Rahul, der Trollige (Gast)


Lesenswert?

Dann mach mal bitte folgende beiden Änderungen (die ich oben auch schon 
vorgeschlagen habe...):

(Irgendwo) vor der While-Schleife:

State = FIND_SEMICOLON;

Pack mal das "printf( "Naechstes Zeichen: %c\n", NextChar );" vor die 
If-Abfrage mit "continue".

von Flo (Gast)


Lesenswert?

in dem geposteten von 14:12 sind deine änderungen schon enthalten

von Rahul, der Trollige (Gast)


Lesenswert?

acho.. Mist

von Flo (Gast)


Lesenswert?

bin nicht unbedingt auf dieses protokoll angewiesen. wenn du/ihr eine 
andere idee habt gerne. bedingungen: s1 auf pa0, ...., s8 auf pa7. am 
ende soll ein array ausgegeben werden, in dem die eingelesenen werte an 
der entsprechenden stellt stehen - [sensor1 sensor2 ....].

von Rahul, der Trollige (Gast)


Lesenswert?

>wenn du/ihr eine andere idee habt gerne.

Schweinemethode:
1
do
2
{
3
 Sensor_Nummer = USART_RX();
4
 if ((Sensor_Nummer >="1") && (Sensor_Nummer <="9")) 
5
 {
6
   Sensor_Nummer = Sensor_Nummer - '1';
7
   Werte[Sensor_Nummer] = read_adc( Sensor_Nummer );
8
 }
9
} while(Sensor_Nummer!= 0x0D);

  

von Rahul, der Trollige (Gast)


Lesenswert?

Ich würde übrigens den Empfang per Interrupt und Ringpuffer machen.

Richtig:
1
do
2
{
3
 Sensor_Nummer = USART_RX();
4
 if ((Sensor_Nummer >='1') && (Sensor_Nummer <='9')) 
5
 {
6
   Sensor_Nummer = Sensor_Nummer - '1';
7
   Werte[Sensor_Nummer] = read_adc( Sensor_Nummer );
8
 }
9
} while(Sensor_Nummer!= 0x0D);

von Sonic (Gast)


Lesenswert?

Hast du mal dran gedacht dass du nach dem Umschalten des ADMUX eine 
Pause von min. 40µs machen musst? Beim Umschalten der Betriebsart 
(single-ended <=> differentiell) sogar 120µs. Wenn du das nicht tust 
kommt bei der Messung nur Mist 'raus!

von Rahul, der Trollige (Gast)


Lesenswert?

>Pause von min. 40µs machen musst?
Wo steht das?

von Sonic (Gast)


Lesenswert?

Im Datenblatt. Atmel gibt noch mehr an, die 40µs habe ich empirisch 
ermittelt.

von johnny.m (Gast)


Lesenswert?

@Sonic:
Jetzt muss ich aber auch mal nachhaken: In welchem Datenblatt und wo da 
genau hast Du irgendwas darüber gelesen, dass man beim Umschalten des 
Kanalmultiplexers eine Wartezeit einhalten muss? Ich habe im Datenblatt 
nur die Info gefunden, dass man beim Umschalten der *Differenz*-Eingänge 
sowie der Referenz 125 µs warten muss, aber nichts über das Ändern von 
ADMUX...

von Rahul, der Trollige (Gast)


Lesenswert?

Die 125µs habe ich auch gefunden...

von Rahul, der Trollige (Gast)


Lesenswert?

Und die 40µs findet nicht mal die AcrobatReader-Suchfunktion...

von Sonic (Gast)


Lesenswert?

Hmm.. habe grade auch nochmal nachgeschaut und vom MUX auch nichts 
gefunden. Tatsache ist, dass ich das Problem mit dem Scannen mehrerer 
Kanäle auch hatte und das mit der Pause einfach probiert habe. Das 
Ergebnis war, dass bei einer Wartezeit von <40µs die Werte nicht mehr 
stimmten. Probier's doch einfach mal, vielleicht klappt's bei dir auch?!

von Flo (Gast)


Lesenswert?

das ende von der geschichte lautet, kein protokoll! - leider.

die sprünge im array konnte ich nicht erklären bzw. dem entgegen wirken. 
jetzt lese ich einfach alle ports der reihe nach ein. ich weiß, dass man 
das als schmutziges programmieren bezeichnet, doch es geht nicht anders:
1
s1 = read_adc(0);
2
s2 = read_adc(1);
3
s3 = read_adc(2);
4
s4 = read_adc(3);
5
s5 = read_adc(4);
6
s6 = read_adc(5);
7
s7 = read_adc(6);
8
s8 = read_adc(7);
9
10
11
stdout = &mystdout;
12
printf(" Werte: %i, %i, %i, %i, %i, %i, %i, %i\n",s2,s3,s4,s5,s6,s7,s8,s1);

bei der gechifteten ausgabe (wer weiß warum) bekomme ich die gewünschte 
ausgabe hin.
pausen führen zu keinen veränderungen in der darstellung.

dank den fleißigen lesern und schreibern,
habt ein schönes wochenend.

gruß
 Flo

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.