Schwankende AD-Werte?

  • 1
  • 2
  • Page 1 of 2
Harry
Moderator
Avatar
Gender:
Location: zwischen Augsburg und Ulm
Age: 59
Posts: 2089
Registered: 03 / 2003
Subject:

Schwankende AD-Werte?

 · 
Posted: 04.11.2021 - 08:09  ·  #1
Hallo Zusammen,

da es immer wieder vorkommt, verstärkt bei XMegas, möchte ich mal ein Thema starten: Schwankende AD-Werte.
Ich habe aktuell folgenden Aufbau: XMega128A4U, versorgt mit 3.3V von einem Linearregler mit ausgangsseitig über die Platine verteilten 150uF (davon >10 Stück 100nF) bestückt nur mit Keramikkondensatoren. Der Linearregler wird von einer anderen Schaltung, ebenfalls mit Linearregler, mit 5V versorgt und ist eingangsseitig mit 100nF und 2x 10uF Kerko beschaltet.
AVCC-Versorgung über 82uH (hatte nichts anderes in der Bauform da) und 100nF + 1uF.
ADRef intern 1.00V. An den 8 AD-Wandlern hängen 8 Spindeltrimmer, die von einem Schaltregler mit konstant 1V versorgt werden. Der Ausgang des Schaltreglers hat wahrlich genug Siebkondensatoren und sogar eine nachgeschaltete LC-Filterung. Die Last durch die Trimmer beträgt gesamt 10mA.

Wenn ich die ADs auslese, schwanken die Werte um gut +/-40-50 .... hat jemand eine Erklärung warum? Oder muß das so sein?

Gruss
Harry

[Edit]Jeder AD-Eingang ist selbstverständlich mit 100nF & 1uF beschaltet.
[Edit, die 2.]Bild ausgetauscht, war ne sche... Qualität
Attachments
Schwankende AD-Werte?
Filename: ADC.png
Filesize: 317.37 KB
Title:
Download counter: 68
tbegle
Benutzer
Avatar
Gender: n/a
Age: 64
Posts: 150
Registered: 01 / 2018
Subject:

Re: Schwankende AD-Werte?

 · 
Posted: 04.11.2021 - 14:39  ·  #2
Hallo Harry,
ich hab den XMega noch nie eingesetzt (mich erschrecken die vielen Beine, einlöten und so, ich bin ein FAN von fertigen getesteten Modulen) aber ich hatte genau das Problem mit z.B. Ausgang am Controller(3,3V) oder 5V über LInear Regler
Bei genauen (so es die 10bit zulassen) nehme ich generell Ref Dioden 5V oder 2,5V mit 4,7uF Tantal und 100n und die Probleme waren weg!
Die Eingangsbeschaltung spielte dabei keine Rolle! falls der Eingang nicht all zu sehr versaut ist.
Natürlich auf die MASSE und Schleifen achten, aber das weisst du ja.

Gruss
Toni
Mathias
Benutzer
Avatar
Gender: n/a
Location: Weingarten - Baden
Posts: 307
Registered: 07 / 2003
Subject:

Re: Schwankende AD-Werte?

 · 
Posted: 04.11.2021 - 14:50  ·  #3
Kannst den Schaltplan posten?
Vielleicht "beißen" sich die beiden Linearregler wil sie in Reihe geschaltet sind.
Zuviele Keramik-Cs (zu hohe Kapazität 150µF) am Ausgang?
Auch der AD-Wandler Code wäre imteressant zu sehen.
Harry
Moderator
Avatar
Gender:
Location: zwischen Augsburg und Ulm
Age: 59
Posts: 2089
Registered: 03 / 2003
Subject:

Re: Schwankende AD-Werte?

 · 
Posted: 04.11.2021 - 15:09  ·  #4
Hallo Mathias,

ich zeichne prinzipiell keine Schaltpläne - sorry. Das Problem habe ich nicht nur hier, sondern leider viel zu oft. Schlimmer ists geworden seit ich XMegas verwende, bei den Megas ging es noch. Die Auflösung der ADCs habe ich beim XMega schon auf 10 Bit begrenzt (ADC SHR 2) und die im Anfangspost angegebenen Schwankung treten dabei auf, bei 12 Bit ist es deutlich schlimmer.
Ich würde ja den AVFilter benutzen, aber leider ist ein Array in der Form VAR : Array[0..7,0..15] of AVFilter nicht zulässig und ich möchte/muß die Werte in einer Schleife verarbeiten, d.h. die Variablen sollen aufzählbar sein. Merlin wollte das zwar bald implementieren, aber im schlimmsten Fall muß ich es wohl selber programmieren.
Die 5V stammen aus einer Schrittmotorendstufe mit eher wenigen Kondensatoren (ein Motor ist bisher nicht angeschlossen), zwischen diesen 5V und dem 3.3V-Regler befinden sich je 2x 100n und 10µF und außerdem versorgen diese 5V den Schaltregler für 1.0V.
An den 3.3V hängen 5x 10µF, 6x 1µF, 10x 100nF, ein XMega, 2x 74VHC08, 6 LEDs (~2mA) und ein grafisches OLED-Display mit SSD1306 128x64 Pixel.

Gruss
Harry
Mathias
Benutzer
Avatar
Gender: n/a
Location: Weingarten - Baden
Posts: 307
Registered: 07 / 2003
Subject:

Re: Schwankende AD-Werte?

 · 
Posted: 04.11.2021 - 15:26  ·  #5
Quote

Die 5V stammen aus einer Schrittmotorendstufe mit eher wenigen Kondensatoren (ein Motor ist bisher nicht angeschlossen), zwischen diesen 5V und dem 3.3V-Regler befinden sich je 2x 100n und 10µF und außerdem versorgen diese 5V den Schaltregler für 1.0V.
An den 3.3V hängen 5x 10µF, 6x 1µF, 10x 100nF, ein XMega, 2x 74VHC08, 6 LEDs (~2mA) und ein grafisches OLED-Display mit SSD1306 128x64 Pixel.

Müsste passen.
Trotzdem, was macht die Schaltung, wenn sie aus einem Labornetzteil versorgt wird?
Wenn's o.k. ist, vielleicht noch den relevanten Code oder auch mehr posten.
Mathias
Benutzer
Avatar
Gender: n/a
Location: Weingarten - Baden
Posts: 307
Registered: 07 / 2003
Subject:

Re: Schwankende AD-Werte?

 · 
Posted: 04.11.2021 - 15:43  ·  #6
Probiere einen kurzen Draht zwischen den beiden Cs einzulöten.
Attachments
AGND
Filename: tempsnip.png
Filesize: 111.3 KB
Title: AGND
Download counter: 39
Mathias
Benutzer
Avatar
Gender: n/a
Location: Weingarten - Baden
Posts: 307
Registered: 07 / 2003
Subject:

Re: Schwankende AD-Werte?

 · 
Posted: 04.11.2021 - 16:27  ·  #7
Probiere auch einen kurzen Draht zwischen GND-Spannungsregler und GND-XMega.
Den Draht nicht zu dünn wählen!

Generell für die externe Versorgung der Spindeltrimmer mit 1,0 V wäre ein Linearregler zweckmäßiger.
Habe mir den MP2357 angeschaut.
Wie hast Du Pin3 beschaltet?
Was sagt das Oszilloskop zu den 1,0 V, schwingt da was?
Weiß nicht ob der MP2357 so viel Kapazität (50µF)am Ausgang verträgt (Schwingneigung).
Die 3x 10µF an den Spindeltrimmer können durch 3x 100nF ersetzt werden.
Attachments
Schwankende AD-Werte?
Filename: GND.PNG
Filesize: 716.38 KB
Title:
Download counter: 42
Harry
Moderator
Avatar
Gender:
Location: zwischen Augsburg und Ulm
Age: 59
Posts: 2089
Registered: 03 / 2003
Subject:

Re: Schwankende AD-Werte?

 · 
Posted: 04.11.2021 - 16:34  ·  #8
Hi Mathias,

der Code ist kein Geheimnis:
Code

{******************************************************************** Harry ***}
{* Schrittmotorsteuerung                                                      *}
{* Display 128x64 OLED SSD1306                                                *}
{* Endschalter Kanal 1: C,2 und C,3      Kanal 2: C,4 und C,5                 *}
{* Fusstaster C,6 und C,7                                                     *}
{* DIP-Schalter Kanal 1: 1-4 --> B3-B0                                        *}
{*              Kanal 2: 1-4 --> B4-B7                                        *}
{* Motor 1 Enable D,1                                                         *}
{* Motor 2 Enable D,3                                                         *}
{* Motortakt D,2                                                              *}
{* MotorDir D,0                                                               *}
{*                                                                            *}
{*                                                                            *}
{*                                                                            *}
{*                                                                            *}
{******************************************************************************}
Program SMS;

{$NOSHADOW}
{ $WG}                     {global Warnings off}

Device = xmega128A4U, VCC=3.3;                   // könnte auch mit einem XMega64A4U funktionieren,
                                                 // aber ich würde es nicht probieren ;-)
Define_Fuses
  Override_Fuses;
  ProgMode  = PDI;
  ProgFuses = true;
  FuseBits5 = [BodAct1,BodLevel1,BodLevel2];     // 2.8V
  // BOD level 0 falling VCC 1.62V     ohne BodLevelx
  // BOD level 1 falling VCC 1.8V      BodLevel0
  // BOD level 2 falling VCC 2.0V      BodLevel1
  // BOD level 3 falling VCC 2.2V      BodLevel0 & 1
  // BOD level 4 falling VCC 2.4V      BodLevel2
  // BOD level 5 falling VCC 2.6V      BodLevel0 & 2
  // BOD level 6 falling VCC 2.8V      BodLevel1 & 2
  // BOD level 7 falling VCC 3.0V      BodLevel0 & 1 & 2

Import SysTick, TWI_C, LCDGraphic, ADC_A, SwitchPort_G, StepPort;

From System import LongWord, LongInt;
From LCDGraphic import CharSet;                  // block CharSet, pixels}

Define
  OSCtype        = int32MHz,
                   PLLmul = 4,
                   prescB = 1,
                   prescC = 1;
  SysTick        = 10;                           // msec
  StackSize      = $0100, iData;
  FrameSize      = $0100, iData;

  TWIPrescC      = TWI_BR400;

  LCDGraphic     = 128, 64, 8;      {x-pix, y-pix, accesswidth}
  LCDgraphMode   = column, iData;
  DefCharSet     = 'Graphchars.pchr';  {FileName}
  GViewports     = 1, iData;        {logical ViewPorts, scalings}
  TGraphStr      = 16;              {Graphic Text String Length}

  ADCrefA        = Ref100;             // ADC-Referenz 1.00V intern
  ADCprescA      = 512,12;             // Prescaler 256, 12-Bit resolution
  ADCchansA      = [0..7];
  
  SwitchPort_G   = [ES11      , PinC,2]     // EndSchalter 1 Port 1
                   [ES12      , PinC,3]     // EndSchalter 1 Port 2
                   [ES21      , PinC,4]     // EndSchalter 2 Port 1
                   [ES22      , PinC,5]     // EndSchalter 2 Port 2
                   [FT1       , PinC,6]     // FussTaster 1
                   [FT2       , PinC,7]     // FussTaster 2
                   , %11000000;             // entspricht nicht Portbelegung!
  PolarityP_G    = $C0;                     //
  Debounce       = 3;
  
  StepMinFreq    = 100;
  StepMaxFreq    = 5000;
  StepTimer      = Timer_C0;
  StepType       = UserPort;
  StepPort       = PortD.2, PortD.0;
  
Uses udpGraphText;                     // Unit für 3x5 und 5x5 Text

Implementation

{$IDATA}

Const

{------------------------------------------------------------------------------}
{ Type Declarations }
Type

{------------------------------------------------------------------------------}
Const
  TText           : Array[0..7] of String[6] = ('maxSpd','Rotati',
                                                'Accele','bkRota',
                                                ' ----',' ----',
                                                ' ----',' ----');
  EText           : Array[0..7] of String[2] = ('%','Tn','ms','Tn','--','--','--','--');
{------------------------------------------------------------------------------}
{ Var Declarations }
{$IDATA}
Var
  M1En[@PortD,1]  : Bit;                          // Motor 1 Enable high-aktiv
  M2En[@PortD,3]  : Bit;                          // Motor 2 Enable high-aktiv
  PreSet          : Array[0..7] of Integer;       // ADC-Werte
  PS0             : AVFilter[0..15] of Integer;

  DIPS            : Array[0..7] of Boolean;       // DIP-Schalter On=1
  Switch          : Array[0..5] of Boolean;       // EndSchalter On=1
{--- Display-Funktionen Start -------------------------------------------------}
{ functions }
Procedure WriteLCD(Arg:Byte;IsData:Boolean);
  Begin
    If IsData=true
      then
        TWIOutC($3C,$40,Arg);                     // data
      else
        TWIOutC($3C,$80,Arg);                     // command
      EndIf;
  End WriteLCD;


Procedure GraphInit;
  Begin
    mDelay(100);
    WriteLCD($AE,false);                          // display off

    WriteLCD($D5,false);                          // set osc division
    WriteLCD($80,false);                          //

    WriteLCD($A8,false);                          // multiplex ratio
    WriteLCD($3F,false);                          // duty=1/32

    WriteLCD($D3,false);                          // set vertical shift by COM
    WriteLCD($00,false);                          //

    WriteLCD($8D,false);                          // set charge pump enable
    WriteLCD($14,false);                          // $10=disable

    WriteLCD($20,false);                          // set memory addressing mode
    WriteLCD($02,false);                          // page addressing mode $02

    WriteLCD($C8,false);                          // COM scan direction/vertical mirror

    WriteLCD($DA,false);                          // set COM pins
    WriteLCD($12,false);                          //

    WriteLCD($81,false);                          // contrast control
    WriteLCD($A0,false);                          // 0-255

    WriteLCD($21,false);                          // set column address
    WriteLCD($00,false);                          // start
    WriteLCD($7F,false);                          // end

    WriteLCD($22,false);                          // set address of display data RAM
    WriteLCD($00,false);                          // start
    WriteLCD($7F,false);                          // end

    WriteLCD($40,false);                          // set display start line

    WriteLCD($00,false);                          // set lower column address
    WriteLCD($10,false);                          // set higher column address
    WriteLCD($B0,false);                          // set page address

    WriteLCD($A1,false);                          // set segment remap/horizontal mirror
    WriteLCD($A6,false);                          // normal/$A7=inverse

    WriteLCD($D9,false);                          // set pre-charge period
    WriteLCD($1F,false);                          //

    WriteLCD($DB,false);                          // set vcomh
    WriteLCD($20,false);                          //

    WriteLCD($AF,false);                          // display on
    mDelay(50);
  End GraphInit;


{$D-}
UserDevice GraphIOS(Cmd: Byte; Arg: Byte);
  Begin
    If cmd = 0
      then
        WriteLCD($02,false);                     // Column 0 --> RAM $02
        WriteLCD($10,false);
        WriteLCD($B0+Arg,false);
      else
        WriteLCD(Arg,true);
      EndIf;
  End GraphIOS;
{$D+}


Procedure SetContrast(co:Byte);
  Begin
    WriteLCD($81,false);                          // contrast control
    WriteLCD(co,false);                           // 0-255
  End SetContrast;


Procedure SetInverse(inv:Boolean);
  Begin
    If inv=true
      then
        WriteLCD($A7,false);                      // inverse
      else
        WriteLCD($A6,false);                      // normal
      EndIf;
  End SetInverse;


Procedure MirrorH(mir:Boolean);                   // mirror horizontal
  Begin
    If mir=true
      then
        WriteLCD($A0,false);                      // mirrored
      else
        WriteLCD($A1,false);                      // normal
      EndIf;
  End MirrorH;


Procedure MirrorV(mir:Boolean);                   // mirror vertical
  Begin
    If mir=true
      then
        WriteLCD($C0,false);                      // mirrored
      else
        WriteLCD($C8,false);                      // normal
      EndIf;
  End MirrorV;
{--- Display-Funktionen Ende --------------------------------------------------}

{--- Startsequenz/Initalisierungen Start --------------------------------------}
Procedure InitPorts;                             // Ports konfigurieren
  Begin                                          // DDRx:  0=Eingang / 1=Ausgang
    DDRA:= %00000000;                            // Trimmer2: 1 2 3 4 Trimmer2: 1 2 3 4
    DDRB:= %00000000;                            // nc nc nc nc Sw1: 1 2 3 4
    PortB:=%00000000;                            // xxx xxx xxx xxx Sw1: 1 2 3 4
    DDRC:= %00000000;                            // FT; Ö S ES2: 2 1 ES1: 2 1 | SCL SDA
    DDRD:= %00001111;                            // Sw2: 4 3 2 1 SMEn2 SMClk SMEn1 SMDir
    PortD:=%00000000;                            //
  End InitPorts;


Procedure Start;
  Begin
    MirrorH(false);
    MirrorV(false);
    SetInverse(false);
    SetContrast($40);
    gClrScr(0);
    gSetTextMode(wmSetPix);
    gSetTextBkGnd(bkTransp);
    gSetTextJustify(alHorCenter, alVertTop);
    gDispRefresh;
    gDrawString(32,-2,2,2,TxtRot0,'SMS');
    gDrawString(32,14,2,1,TxtRot0,'V1.0');
    gDrawString(22,55,1,1,TxtRot0,'(C)2021');
    gDrawString(47,27,3,3,TxtRot0,'C');
    gDrawString(53,41,3,3,TxtRot0,'H');
    gDispRefresh;
    mDelay(5000);
    gSetTextBkGnd(bkNormal);
    gSetTextJustify(alHorLeft, alVertTop);
    gClrScr(0);
    gDispRefresh;
  End Start;
{--- Startsequenz/Initalisierungen Ende ---------------------------------------}
//UserDevice StepperIOS(cw:boolean);
//  Begin
//  End StepperIOS;
  

Procedure ShowPreSet;
  Var Counter : Byte;
  Begin
    gDrawString(106,-2,1,1,TxtRot0,'ADC');
    For Counter:=0 to 7 do
      PreSet[Counter]:=Integer(GetADCA(7-Counter)) SHR 2;
      chDraw5x5(105,(Integer(Counter)*7)+10,TxtRot0,IntToStr(PreSet[Counter]:4:'0'));
      EndFor;
  End ShowPreSet;
  
  
Procedure ShowDIPS;
  Var Counter : Byte;
  Begin
    gDrawString(90,-2,1,1,TxtRot0,'Sw');
    For Counter:=0 to 7 do
      If Counter in [0..3]
        then
          DIPS[Counter]:=not Bit(PinB,3-Counter);
        else
          DIPS[Counter]:=not Bit(PinD,Counter);
        EndIf;
      If DIPS[Counter]=true
        then
          chDraw5x5(95,(Integer(Counter)*7)+10,TxtRot0,'1');
        else
          chDraw5x5(95,(Integer(Counter)*7)+10,TxtRot0,'0');
        EndIf;
      EndFor;
  End ShowDIPS;
  
  
Procedure ShowSwitch;
  Var Counter : Byte;
  Begin
    gDrawString(-2,-2,1,1,TxtRot0,'PE');
    Switch[0]:=Inp_Raise_G(ES11);
    Switch[1]:=Inp_Raise_G(ES12);
    Switch[2]:=Inp_Raise_G(ES21);
    Switch[3]:=Inp_Raise_G(ES22);
    Switch[4]:=Inp_Raise_G(FT1);
    Switch[5]:=Inp_Raise_G(FT2);
    SwitchPort_G_Clear;
    
    For Counter:=0 to 5 do
      If Switch[Counter]=true
        then
          Case Counter of
            0..1:chDraw5x5(2,(Integer(Counter)*7)+10,TxtRot0,'1');|
            2..3:chDraw5x5(2,(Integer(Counter+5)*7)+10,TxtRot0,'1');|
            4..5:chDraw5x5(2,(Integer(Counter-1)*7)+10,TxtRot0,'1');|
            EndCase;
        else
          Case Counter of
            0..1:chDraw5x5(2,(Integer(Counter)*7)+10,TxtRot0,'0');|
            2..3:chDraw5x5(2,(Integer(Counter+4)*7)+10,TxtRot0,'0');|
            4..5:chDraw5x5(2,(Integer(Counter-1)*7)+10,TxtRot0,'0');|
            EndCase;
        EndIf;
      EndFor;
  End ShowSwitch;
  
  
Procedure ShowText;
  Var Counter : Byte;
  Begin
    For Counter:=0 to 7 do
      chDraw3x5(48,(Integer(Counter)*7)+10,TxtRot0,EText[Counter]);
      chDraw3x5(62,(Integer(Counter)*7)+10,TxtRot0,TText[Counter]);
      EndFor;
  End ShowText;
    
{------------------------------------------------------------------------------}
{ Main Program }
{$IDATA}
Begin
  EnableInts($87);
  GraphInit;
  Start;
  Loop
    ShowPreSet;
    ShowDIPS;
    ShowSwitch;
    ShowText;
    gDispRefresh;
    mDelay(200);
    Endloop;
End SMS.


Das ist so übrigens nicht compilierbar, weil UserDevice SteppIOS fehlt. Das dürfte aber bei definiertem Clock-/Dir-Port nicht sein und bei alten Projekten mit Mega644 geht es auch.

Gruss
Harry
  • 1
  • 2
  • Page 1 of 2
Selected quotes for multi-quoting:   0

Registered users in this topic

Currently no registered users in this section

The statistic shows who was online during the last 5 minutes. Updated every 90 seconds.
MySQL Queries: 18 · Cache Hits: 15   143   158 · Page-Gen-Time: 0.03217s · Memory Usage: 2 MB · GZIP: on · Viewport: SMXL-HiDPI