Forum: Mikrocontroller und Digitale Elektronik TTL Pegel 6x4 von Inkrementalmessystem Verarbeiten und mit XMega auswerten


von Alexej W. (gluon)


Angehängte Dateien:

Lesenswert?

Hallo liebe Community,

Momentan bin ich dabei mein Inkrementalmesssystem (Anbaumessschieber von 
Wabeco) mit einem XMega zu verheiraten, damit ich diesen an meiner Fräse 
anbauen kann...
In diesem Beitrag wollte ich die Fachmeinung der Kenner wissen (bin 
selbst kein Elektrotechniker). Zur Allererst habe ich mit einem 
Oszilloscop die Ausgänge des Messschiebers überprüft. Ich messe auf der 
Taktleitung ein Paket, welches etwa 12,5 ms lang ist, danach kommt 170 
ms nichts dann kommt das gleiche Paket wieder. Ein Bild des Oszis ist 
angehängt Oszi1.PNG.
----------------Oszi1.PNG-----------------
Anscheinend arbeitet der Messschieber intern in 1/100 mm, denn wenn ich 
die Messleiste um 0,01 mm verschiebe, so verschwindet auf der 
Datenleitung (Gelb) das erste "Bit" (oder wie heißt es in den 
Fachkreisen?). Die negativen Werte sieht man anhand des letzten Paket. 
Denn dort wird der erste Bit dann "Low" (die restlichen überflüssig). Zu 
sehen in dem Bild Oszi2.PNG
----------------Oszi2.PNG-----------------
Um die Daten auszulesen brauche ich also nur 2 Pins. Bei diesen wird 
dann der Zustand verglichen und bei Übereinstimmung ist der Bit 0 bei 
Nichtübereinstimmung ergibt es eine 1. Sollte man eine Funktion zum 
vergleichen schreiben, welche dann binären Wert liefert. Auf diese 
Funktion wird von einer anderen Zugegriffen, welche den Wert dann 
zusammensetzt zu einem Integer. Und dieser Integer ist mein Messwert.
----> Zu den Fragen <----
1.) Ist der Gedankengang ok?
2.) Gibt es eine elegantere Methode den Pegel auszulesen?
3.) Meinen XMega will ich mit 3,3 V Betreiben (denn sonst mein LCD-Modul 
Probleme macht), der Messschieber arbeitet bei 1,5 Volts. Ich will einen 
4fachen Operationsverstärker nehmen und diesen in einer 
nichtinvertierender Verstärkerschaltung betreiben um die Spannung zu 
verdoppeln (zwei TS272). Ist es eine optimale Lösung?
4.) Idee ist, dass der Mikrokontroller eine lineare Regression ausführt 
und intern nach einer Kalibrierung mittels Prüf-Messwerte die 
Berechneten(theoretisch richtigen) Werte für die Messung anzeigt. 
Schafft ein Mikrokontroller eine Lineare Regression zu berechnen? Und 
das Alles soll für 4 Messschieber Funktionieren!?!?

Ich bitte sie um konstruktive Beiträge
Viele Grüße Alex

von Rainer U. (r-u)


Lesenswert?

Du kannst z.B. die vorhandene SPI-SChnittstelle von Deinem XMega 
benutzen, die ist speziell für sowas gemacht. Dann liest Du 3 Byte ein 
und baust daraus ein Long integer, damit kannst Du alle Werte abbilden, 
die das Ding liefern kann.

Zur Anpassung der Pegel gibt es Artikel in der Artikelsammlung.

"lineare Regression" ist ein bischen hochgreifend formuliert. Wieviele 
Kalibrierungspunkte hast Du denn? Wenn es nur Anfang und Ende mit den 
jeweiligen Messwerten sind, dann ist der Rest ein Dreisatz. Dass schafft 
der uC.. :-)

Für 4 Signale kannst Du entweder mehrere SPI -Schnittstellen als 
Software emulieren, oder Du baust Dir aus Logikbausteinen einen 
Umschalter, mit dem Du immer nur ein Leitungspaar zur SPI durchlässt.

von Alexej W. (gluon)


Lesenswert?

Danke für deine Antwort!

SPI zu benutzen ist eine sehr gute Idee.
Habe mir nun eine Bidirektionalen 8-Bit Pegelwandler besorgt, durch den 
ich meine 3,3V für Mikrocontroller bekomme.

Habe bischen im Datenblatt des X-Mega's bezüglich der SPI-Interfaces 
gelesen. Da steht, dass man ja nur 4 Register braucht. Das CTRL, 
INTCTRL, STATUS und DATA.
In das CTRL-Register schreibe ich eine 0x6C da es ja gerade meinen 
einstellungen entspricht: 01101100 (Clock-Double ist --> 0, SPI-wird 
eingeschaltet --> 1 ; LSB first --> 1 ; Slave-Modus --> 0 ; SPI-Mode 3 
--> 1 --> 1 und Prescaler --> 0 --> 0 ) das in Hexadezimal: 0x6C, also 
CTRL = 0x6C. Das INTCTRL setze ich 0.

Wenn ich nun auf dem Steckboard das alles verdrahte und LCD anschließe, 
so bekomme ich wirre werte...

Mit dem STATUS Register habe ich schwierigkeiten...
Ich Kriege je von dem Messschieber 24 Bits, das sind 3 mal 8-Byte 
Pakete. Ich muss also irgendwie den DATA-Register mit hilfe des STATUS 
Registers 3 mal pro Datenübertragung auslesen und dabei einen uint32_t 
erzeugen ?.?.?.? weiß momentan nicht weiter. Kann mir eventuell jemand 
Literaturhinweis geben?

Hier mein Code:
1
/*
2
 * ATXmega16A4_AU.c
3
 *
4
 * Created: 01.10.2012 21:06:30
5
 *  Author: Alex
6
 */ 
7
8
#define F_CPU 32000000UL      
9
#define FALSE 0;
10
#define TRUE 1;
11
12
13
#include <avr/io.h>
14
#include <util/delay.h>
15
#include "lcd-routines.h"
16
17
// Das ist eine Funktion zur Einstellung des internen 32 MHz Schwingers
18
19
void Clock_init(void)
20
{
21
  OSC.CTRL |= OSC_RC32MEN_bm;
22
  while(!(OSC.STATUS & OSC_RC32MRDY_bm));
23
  CCP = CCP_IOREG_gc;
24
  CLK.CTRL = 0x01;
25
}
26
27
int main(void)
28
{  
29
  Clock_init();
30
  
31
  lcd_init();
32
    
33
  SPIC.CTRL = 0x6C; //Setzen des CTRL-Registers
34
  SPIC.INTCTRL = 0;
35
  uint32_t i = 0;
36
  char puffer[20];
37
  lcd_clear();
38
  lcd_string("Anzeige: ");
39
    
40
  while(1)
41
  {
42
      i = SPIC.DATA;
43
      ultoa(i, puffer, 10 );
44
      lcd_setcursor(9,1);
45
      lcd_string( puffer );
46
      _delay_ms(10);
47
  }
48
    
49
  return 0;
50
}



---------------- Zur Linearen Regression ------------------
Zur Kalibrierung habe ich 7 Wertepaare alle symmetrisch entlang 175 mm 
verteilt mit Genauigkeit von unter pm 0,01 mm. Die Abschätzung des 
Quadrat der Standartabweichung lautet:
Nun minimiert man die Parameter bezüglich a und b:
ergibt sich das Gleichungsystem:
Als Lösung des Gleichungsystems erhält man:
und für den Linearen Koeffizienten b:
Hier ist D die Determinante und beträgt:

Wie man nun sieht müssen die 3-fachen Produkte berechnet werden über die 
Summen der Wertepaare. hmmm Schafft der Mikrokontroller das?

von Michael (Gast)


Lesenswert?

Alexej W. schrieb:
> Zur Kalibrierung habe ich 7 Wertepaare alle symmetrisch entlang 175 mm
> verteilt mit Genauigkeit von unter pm 0,01 mm.

Und wie liegen deine Werte in Relation zu einer Geraden. Eine 
Kalibrierung ist nur sinnvoll, wenn der Zusammenhang reproduzierbar ist 
und nicht bei der nächsten Kalibiermessung ganz anders aussieht. Ggf. 
benötigt man z.B. zusätzlich einen Temperaturfühler für Korrekturen.

von Alexej W. (gluon)


Lesenswert?

Japp das ist dann für Später als Erweiterung gedacht.
Aktuell lese ich die Werte manuell ab und berechne diese mit einem 
kleinen Progrämmchen, die Berechnung dauert zwar kurz auf meinem 
Werkstatt-Rechner, geht aber. Die Werte weisen eine sehr gute Linearität 
auf, so dass es wie oben erwähnt nur von der Umgebungstemperatur und dem 
linearen Wärmeausdehnungskoeffizienten abhängt.
Später wollte ich einen PT100 oder sowas an Mikrokontrollen anschließen, 
welcher dann vergleicht ob die Temperatur im Raum sich geändert hat oder 
nicht und dann etscheidet ob eine neue Kalibrierung vorgenommen werden 
muss....

von Alexej W. (gluon)


Lesenswert?

Hallo,
Bitte um Hilfe bezüglich Code...
Habe nun bischen recheschiert und herausgefunden was ich brauche, es 
klappt jedoch nicht!

Ich muss also 3 Bytes nacheinander auslesen und diese dann in ein 
uint32_t zusammenfügen. Danach muss ich ja den Wert einmal spiegeln und 
dann ist er theoretisch fertig.
Hier mein Code:
1
/*
2
 * ATXmega16A4_AU.c
3
 *
4
 * Created: 01.10.2012 21:06:30
5
 *  Author: Alex
6
 */ 
7
8
#define F_CPU 32000000UL      
9
#define FALSE 0;
10
#define TRUE 1;
11
12
13
#include <avr/io.h>
14
#include <util/delay.h>
15
#include "lcd-routines.h"
16
17
18
//Funktion zur Einstellung des internen 32 MHz Schwingers
19
void Clock_init(void)
20
{
21
  OSC.CTRL |= OSC_RC32MEN_bm;
22
  while(!(OSC.STATUS & OSC_RC32MRDY_bm));
23
  CCP = CCP_IOREG_gc;
24
  CLK.CTRL = 0x01;
25
}
26
27
//SPI-Schnitstelle Initialisieren
28
void Spi_init(void)
29
{
30
  SPIC.CTRL = 0b01101100;      //Control-Register: 0b01101100 -> (Clock-Double -> 0, SPI einschalten -> 1, LSB first -> 1, Slave-Modus -> 0, SPI-Mode 3: -> 1 -> 1, Prescaler: -> 0 -> 0)
31
  SPIC.INTCTRL = 0x00;      //Interrupt-Register: 0b00000000 -> (Reserviert -> 0 -> 0 -> 0 -> 0 -> 0 -> 0, Interrupt-Level: OFF -> 0 -> 0 )
32
}
33
34
//3 Bytes aus dem SPI Auslesen und in ein uint32_t reinschreiben
35
uint32_t spi_bytes_empfangen(void)
36
{
37
  uint32_t data = 0;      
38
  data = SPIC.DATA;        //Daten-Register auslesen
39
  data <<= 8;            //data um 8 Bits nach links schieben
40
  data |= SPIC.DATA;        //hänge ein Byte aus dem Daten-Register rechts an data an
41
  data <<= 8;            //data um 8 Bits nach links schieben
42
  data |= SPIC.DATA;        //hänge ein Byte aus dem Daten-Register rechts an data an
43
  return data;          //Ausgabe des data-Wertes
44
}
45
46
//Spiegelung eines uint32_t, hier wird bitweise der neue uint32 zusammengesetzt
47
uint32_t spiegelnuint32(uint32_t input)
48
{
49
  uint32_t output=0;
50
  for(uint8_t i=1;i<=32;i++)
51
  {
52
    output |= input & i << (32-i);
53
  }
54
  return output;
55
}
56
57
int main(void)
58
{  
59
  Clock_init();
60
  Spi_init();
61
  lcd_init();
62
  
63
  uint32_t i;          
64
  char puffer[20];                  //Anlegen eines Strings von Länge 20 Zeichen
65
  lcd_clear();
66
  lcd_string("Anzeige X: ");    
67
    
68
  while(1)
69
  {
70
    i=0;
71
    i = spiegelnuint32(spi_bytes_empfangen());    //Hier wird nun der empfangene uint32_t gespiegelt und dem i zugewiesen
72
    ultoa(i, puffer, 10 );              //Funktion zur Umwandlung eines Unsignet-Longs zu String puffer in der Dezimalen Darstellung
73
    lcd_setcursor(11,1);
74
    lcd_string( puffer );
75
  }
76
    
77
    return 0;
78
}

Wenn ich das Programm compiliere, so sehe ich auf dem LCD als Position 
0, sobalt ich den Messchieber um 0,01mm bewege ändert sich der Wert 
sofort auf 05792. Bei Wert 0,02 mm ist LCD bei 031586. Wenn ich nun den 
Messschieber resete, dann ist die LCD-Anzeige bei dem alten Wert, obwohl 
nach einem Reset die Data-Leitung eine 0 liefert...
Sehe momentan keinen Fehler im Code.

Bitte um Hilfe
Grüße Alex

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.