www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Ausgabe der AD-Wandlung


Autor: Flo (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Wenn Du ein Array mit
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.

Autor: Flo (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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!
  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' - 1;
            read_adc( Sensor_Nummer );
            Werte[Sensor_Nummer] = ADCW;
          }
          State = FIND_SEMICOLON;
          break;

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


  

Autor: Flo (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Rahul, der Trollige (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Sensor_Nummer = NextChar - '1';

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

Autor: Flo (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Werner B. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Vorsichtshalber noch...
...
while( Buffer[Index] != 0 && Buffer[Index] != '_' )
...
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...
...
if( NextChar > '0' && NextChar < '9' )
...

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

Autor: Flo (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Flo (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Flo (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Rahul, der Trollige (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>sorry für die kryptische darstellung... füge immer kopierten code ein...

Wenn du da vor ein
 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.

Autor: Rahul, der Trollige (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
ich bin sooooooo doof!

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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Rahul hat recht.
Bau doch mal ein paar printf ein, damit du siehst was
überhaupt passiert:

// Endlosschleife

  stdout = &mystdout;

  while(1)
  {

    uart_gets(Buffer);
    printf( "%s\n", Buffer );

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

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

      printf( "Naechstes Zeichen: %c\n", NextChar );

      switch( State )
      {
        case START_SENSOR_AUSWAHL:
          printf( "Im Status SENSOR_AUSWAHL\n" );

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

        case FIND_SEMICOLON:
          printf( "Im Status FIND_SEMICOLON\n" );
          if( NextChar == ';' )
          {
            State = START_SENSOR_AUSWAHL;
          }
        // Ende vom switch
      }

     // Ende vom while(Buffer)
    }


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?

Autor: Flo (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Flo (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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
#include <avr/io.h>
#include <stdio.h>
#include <string.h>

#define START_SENSOR_AUSWAHL  0
#define FIND_SEMICOLON        1    

int State =0;
int Index;
int Sensor_Nummer;
int Werte[8] = {0,0,0,0,0,0,0,0};

char NextChar;
char Buffer[40];



static int uart_putchar(char c, FILE *stream);
static FILE mystdout = FDEV_SETUP_STREAM(uart_putchar, NULL,
                                             _FDEV_SETUP_WRITE);

static int
    uart_putchar(char c, FILE *stream)
    {

      if (c == '\n')
        uart_putchar('\r', stream);
      loop_until_bit_is_set(UCSRA, UDRE);
      UDR = c;
      return 0;
    }



void uart_putc( char c )
{
  // Warte bis die Sendeeinheit bereit ist
  while( !(UCSRA & ( 1<<UDRE) ) )
    ;
  UDR = c;
}



void uart_puts( const char* str )
{
  while( *str ) 
  {
    uart_putc( *str );
    str++;
  }
}


unsigned char USART_RX(void)
{
  while(!(UCSRA&(1<<RXC)))
    ;
  return UDR;
}


void uart_gets( char* Input )
{
  char c = USART_RX();

  while( c != '_' ) 
  {
    *Input = c;
    Input++;
    c = USART_RX();
  }
  *Input = '\0';
}


void uart_init(void)
{
  // USART Baud rate: 19.200 bps
  UBRRH = 0x00;  
  UBRRL = 0x0B;
  UCSRA = 0x00;
  UCSRB = 0x18;
  UCSRC = 0x86;
}


#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;
}

int main(void)
{
ADMUX=ADC_VREF_TYPE;
ADCSRA=0xA5;
SFIOR&=0x1F;

uart_init();

// Endlosschleife
while(1)
 {
 
uart_gets(Buffer);
printf( "%s\n", Buffer );

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

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

   printf( "Naechstes Zeichen: %c\n", NextChar );

   switch( State )
     {
        case START_SENSOR_AUSWAHL:
          printf( "Im Status SENSOR_AUSWAHL\n" );

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

        case FIND_SEMICOLON:
          printf( "Im Status FIND_SEMICOLON\n" );
          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
}
// Ende der main
}

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

Autor: Rahul, der Trollige (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Könntest du vielleicht noch ein UART-Log liefern?

Autor: Flo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
was meinst du damit?

Autor: Rahul, der Trollige (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>State = START_SENSOR_AUSWAHL;

Ersetz das als Startwert mal durch:
State = FIND_SEMICOLON;

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

Autor: Rahul, der Trollige (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Könntest du vielleicht noch ein UART-Log liefern?

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

Autor: Flo (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Rahul, der Trollige (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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;

Autor: Flo (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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...

Autor: Rahul, der Trollige (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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".

Autor: Rahul, der Trollige (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Noch was: Soll die Eingabe von Menschen gemacht werden?

Autor: Flo (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Rahul, der Trollige (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Flo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
alles noch so wie zuvor gepostet!
nur das eine endezeichen ist eine raute geworden....

Autor: Rahul, der Trollige (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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".

Autor: Flo (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
in dem geposteten von 14:12 sind deine änderungen schon enthalten

Autor: Rahul, der Trollige (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
acho.. Mist

Autor: Flo (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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 ....].

Autor: Rahul, der Trollige (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>wenn du/ihr eine andere idee habt gerne.

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

  

Autor: Rahul, der Trollige (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Ich würde übrigens den Empfang per Interrupt und Ringpuffer machen.

Richtig:
do
{
 Sensor_Nummer = USART_RX();
 if ((Sensor_Nummer >='1') && (Sensor_Nummer <='9')) 
 {
   Sensor_Nummer = Sensor_Nummer - '1';
   Werte[Sensor_Nummer] = read_adc( Sensor_Nummer );
 }
} while(Sensor_Nummer!= 0x0D);

Autor: Sonic (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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!

Autor: Rahul, der Trollige (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Pause von min. 40µs machen musst?
Wo steht das?

Autor: Sonic (Gast)
Datum:

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

Autor: johnny.m (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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...

Autor: Rahul, der Trollige (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die 125µs habe ich auch gefunden...

Autor: Rahul, der Trollige (Gast)
Datum:

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

Autor: Sonic (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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?!

Autor: Flo (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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:
s1 = read_adc(0);
s2 = read_adc(1);
s3 = read_adc(2);
s4 = read_adc(3);
s5 = read_adc(4);
s6 = read_adc(5);
s7 = read_adc(6);
s8 = read_adc(7);


stdout = &mystdout;
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

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.