Forum: Compiler & IDEs Pixy Pet - Probleme SPI


von cnc13 (Gast)


Lesenswert?

Moin,

ich bin neu hier und dachte ihr könnt mir bei meinem Problem helfen.

Ich habe folgendes Problem. Und zwar arbeite ich an einem Roboter, der 
Objekten folgen soll.
Nun möchte ich, dass der Atmega32u4 auf dem Arduino Leonardo Rev. 3 über 
den SPI bus mit der Pixy Cam (CMUcam5) kommuniziert, was nicht ganz 
funktioniert wie ich unten weiter beschreibe.

Während meiner auseinandersetzung mit dem Problem habe ich folgende 
Erkenntnis bin ich gemacht:
- Ich kann über die Schnittstelle des Arduinos mit der Pixy-Cam 
kommunizieren, dies aber nur in eine Richtung (Von Pixy-Cam zu Arduino).
- Ich erhalte einen 16 bit Wert mit dem niederwertigsten Byte als 
erstes.
- Die Sync-Bytes sind das einzig sinnvolle was ich bekomme (Checksum 
stimmt vom Rest nicht).

hier der link zu der Seite wo das alles beschrieben ist:

http://www.cmucam.org/projects/cmuca.../Porting_Guide

Und im Anschluss nochmal der überarbeitete Code.

Meine Probleme sind:

- Daten über SPI von Arduino zu Pixy schicken.
- Vernünftige Daten erhalten nach den Sync-Bytes (Checksum)

Ich hoffe ihr könnt mir helfen.
Danke im Voraus :)
1
#define F_CPU 16000000UL
2
3
#define UARTaktiv //Auskommentieren, um UART zu deaktivieren
4
5
#include <avr/io.h>
6
#include <util/delay.h>
7
#include <avr/interrupt.h>
8
9
void TimerInit ()
10
{
11
  TCCR1A=0b10100001;
12
  TCCR1B=0b00000011;
13
  DDRB=(1<<PINB6) | (1<<PINB5);
14
}
15
16
  
17
  void USART_init(uint8_t baud)
18
  {
19
    
20
    /*Setzen der Baudrate (Übertragungsrate)*/
21
    UBRR1H = (unsigned char) (baud>>8);
22
    UBRR1L = (unsigned char) baud;
23
    
24
    /*Aktivieren von Empfänger(RX) und Sender(TX)*/
25
    UCSR1B = (1<<RXEN1) | (1<<TXEN1);
26
    
27
    /*Setzen des Formates: 8bit Groß, 2bits zum Stoppen*/
28
    UCSR1C = (1<<USBS1) | (3<<UCSZ10);
29
    
30
  }
31
  
32
  void USARTTransmit (unsigned char data)
33
  {
34
    /*Auf leeren Übertragungspuffer warten*/
35
    while (!(UCSR1A & (1<<UDRE1)) );
36
    
37
    /*Packe die Daten in den Puffer und sende diese*/
38
    UDR1 = data;
39
  }
40
  
41
  void USART_Recieve()
42
  {
43
    /*Warte auf Empfangen von Daten*/
44
    while (!(UCSR1A &(1<<RXC1)) );
45
    
46
    /*Bekomme die Daten vom Puffe und gebe sie zurück*/
47
    return UDR1;
48
  }
49
  
50
void SPIinit(void)
51
{
52
  DDRB = (1<<PINB1)|(1<<PINB2)|(1<<PINB0);
53
  SPCR = 0b01110001;
54
  SPSR= 0;
55
}
56
unsigned char SPI_start(unsigned char cData)
57
{
58
  SPDR = cData;
59
  while(!(SPSR & (1<<SPIF)));
60
  return SPDR;
61
}
62
63
uint8_t SensorArray()
64
{
65
[...]
66
}
67
68
void PullupSet()
69
{
70
  PORTB = (1<<PINB7);
71
  PORTC = (1<<PINC6);
72
  PORTD = (1<<PIND4);
73
  PORTF = (1<<PINF7) | (1<<PINF5) | (1<<PINF4);
74
}
75
76
77
int main(void)
78
{
79
  uint16_t ObjectBlock;
80
  uint16_t Checksum;
81
  uint16_t signatureNr;
82
  uint16_t xposition;
83
  uint16_t yposition;
84
  uint16_t width;
85
  uint16_t height;
86
  uint16_t count;
87
  uint8_t buffer;
88
  
89
  uint8_t sig1;
90
  uint8_t sig2;
91
92
  TimerInit();
93
   USART_init(103);
94
  PullupSet();
95
   SPIinit();
96
97
    while(1)
98
    {
99
    count++;
100
    buffer=SPI_start(0xFF);
101
    
102
    if(buffer==0xAA )
103
    {
104
      count=0;
105
      sig1 =(buffer);
106
    }
107
    else if (count==1)
108
      sig2 =(buffer);  
109
    else if (count==2)
110
      Checksum=buffer;
111
    else if (count==3)
112
      Checksum=Checksum+buffer<<8;
113
    else if (count==4)
114
      signatureNr = buffer;
115
    else if (count==5)
116
      signatureNr+= buffer<<8;
117
    else if (count==6)
118
      xposition=buffer;
119
    else if (count==7)
120
      xposition+=buffer<<8;  
121
    else if (count==8)
122
      yposition=buffer;
123
    else if (count==9)
124
      yposition=yposition+buffer<<8;
125
    else if (count==10)
126
      width=buffer;
127
    else if (count==11)
128
      width=width+buffer<<8;  
129
    else if (count==12)
130
      height=buffer;
131
    else if (count==13)
132
      height=height+buffer<<8;    
133
134
    if ((sig1==0xAA) && (sig2==0x55))
135
    {
136
    USARTTransmit((uint8_t)((xposition & 0xff00)>>8));
137
    USARTTransmit((uint8_t)(xposition & 0x00ff));
138
    USARTTransmit(sig1);
139
    USARTTransmit(sig2);
140
    USARTTransmit((uint8_t)((Checksum & 0xff00)>>8));
141
    USARTTransmit((uint8_t)(Checksum & 0x00ff));
142
    USARTTransmit((uint8_t)((signatureNr & 0xff00)>>8));
143
    USARTTransmit((uint8_t)(signatureNr & 0x00ff));
144
    USARTTransmit((uint8_t)((xposition & 0xff00)>>8));
145
    USARTTransmit((uint8_t)(xposition & 0x00ff));
146
    USARTTransmit((uint8_t)((yposition & 0xff00)>>8));
147
    USARTTransmit((uint8_t)(yposition & 0x00ff));
148
    USARTTransmit((uint8_t)((width & 0xff00)>>8));
149
    USARTTransmit((uint8_t)(width & 0x00ff));
150
    USARTTransmit((uint8_t)((height & 0xff00)>>8));
151
    USARTTransmit((uint8_t)(height & 0x00ff));
152
    USARTTransmit(13);
153
    }
154
   }
155
}

von Moin (Gast)


Lesenswert?

Ich gehe mal davon aus, dass du dir die Daten nur über den Uart 
anschaust. Der sendet aber jedes mal wenn du ein Byte von deiner Kamera 
bekommen hast, nachdem die SYNC Bytes 1x angekommen sind.

Das Senden
1
if ((sig1==0xAA) && (sig2==0x55))
2
{
3
    ....
4
}
könnte z.b. so aussehen:
1
if ((sig1==0xAA) && (sig2==0x55) && (count>=13))
2
{
3
    .....
4
    sig1=0x00;
5
    sig2=0x00;
6
}

von cnc13 (Gast)


Lesenswert?

Also ich hab das jetzt so gemacht und danach bekomme ich garnix mehr 
über uart rein
1
if ((sig1==0xAA) && (sig2==0x55) && (count>=13))
2
    {
3
    USARTTransmit(sig1);
4
    USARTTransmit(sig2);
5
    USARTTransmit((uint8_t)((Checksum & 0xff00)>>8));
6
    USARTTransmit((uint8_t)(Checksum & 0x00ff));
7
    USARTTransmit((uint8_t)((signatureNr & 0xff00)>>8));
8
    USARTTransmit((uint8_t)(signatureNr & 0x00ff));
9
    USARTTransmit((uint8_t)((xposition & 0xff00)>>8));
10
    USARTTransmit((uint8_t)(xposition & 0x00ff));
11
    USARTTransmit((uint8_t)((yposition & 0xff00)>>8));
12
    USARTTransmit((uint8_t)(yposition & 0x00ff));
13
    USARTTransmit((uint8_t)((width & 0xff00)>>8));
14
    USARTTransmit((uint8_t)(width & 0x00ff));
15
    USARTTransmit((uint8_t)((height & 0xff00)>>8));
16
    USARTTransmit((uint8_t)(height & 0x00ff));
17
    USARTTransmit(13);
18
    }

von Moin (Gast)


Lesenswert?

Porting Guide:
> All values in the object block are 16-bit words, sent least-signifcant
> byte first (little endian). So, for example, when sending the sync word
> 0xaa55, Pixy sends 0x55 (first byte) then 0xaa (second byte).

Du liest die Signatur falsch herum ein. Erst 0x55, dann 0xAA.

Also:
1
if (0x55 == buffer)
2
{
3
    count = 0;
4
    sig1 = buffer;
5
}

und
1
if ((0xAA == sig2) && (0x55 == sig1) && (count>=13))
2
{ ... }

von cnc13 (Gast)


Angehängte Dateien:

Lesenswert?

also ich hab mir jetzt die signature nummer ausgeben lassen und frage 
mich ob das nicht durchgehend 1 sein muss, sobald er was bekommt.

oder sucht der innerhalb von einer sekunde ca 50 mal die signatur neu?

müsste ich dafür ein mittel aus 50 bildern in 1 sekunde ziehen?

von Jeremias E. (Firma: Privat) (cnc13)


Lesenswert?

ich meinte oben den width wert nicht die signature nr sorry

von Moin (Gast)


Lesenswert?

cnc13 schrieb:
> also ich hab mir jetzt die signature nummer ausgeben lassen und frage
> mich ob das nicht durchgehend 1 sein muss, sobald er was bekommt.
>
> oder sucht der innerhalb von einer sekunde ca 50 mal die signatur neu?
>
> müsste ich dafür ein mittel aus 50 bildern in 1 sekunde ziehen?

Ich kann weder mit dem Bild noch mit deinem Text was anfangen. 
Funktioniert die Kommunikation mit der Kamera jetzt richtig?

Falls sich weitere Probleme mit der Kommunikation auftuen kann ich gerne 
versuchen zu helfen, zum Auswerten der Daten der Kamera kann ich nicht 
helfen. Da müsste ich genauso wie du das Manual genauer lesen.

von Jeremias E. (Firma: Privat) (cnc13)


Lesenswert?

Generell bin ich nun ein stück weiter gekommen, aber wenn ich mir nur 
die SigantureNr ausgeben lasse habe ich durchgehend 0x8000 was nicht 
stimmen kann. Keine Ahnung warum. Denn eig müsste dort ne 1 stehen, was 
es aber nicht tut.
Eine 1 deshalb, weil ich der PixyCam nur eine signature eingelesen habe.

von Moin (Gast)


Lesenswert?

Jeremias Esser schrieb:
> Generell bin ich nun ein stück weiter gekommen, aber wenn ich mir
> nur
> die SigantureNr ausgeben lasse habe ich durchgehend 0x8000 was nicht
> stimmen kann. Keine Ahnung warum. Denn eig müsste dort ne 1 stehen, was
> es aber nicht tut.
> Eine 1 deshalb, weil ich der PixyCam nur eine signature eingelesen habe.

0x8000 Bitgespiegelt ist 0x0001. Schau mal ob überall die Bitreihenfolge 
richtig eingestellt ist. Zum Ausschließen von Fehlern einfach mal den 
SPI abklemmen und eine bekannte Information über den UART schicken.

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.