Forum: Mikrocontroller und Digitale Elektronik sx1276 Probleme mit dem RegOpMode


von David P. (devryd)


Lesenswert?

Hallo Zusammen,
ich möchte zwei Raspberry Pi Pico über LoRa (nicht LoRaWAN) miteinander 
reden lassen. Ich habe leider keine passende Library gefunden und 
"entwickle" das ganze deshalb selbst. Ich nutze C und habe die Infos 
alle aus dem Datenblatt. Die SPI Kommunikation mit dem funktioniert, und 
ich kann beispielsweise die Frequenz einstellen. Wenn ich allerdings den 
Modus auf Senden oder Empfangen stellen möchte, funktioniert das ganze 
plötzlich nicht.

Empfänger:
1
#include <stdio.h>
2
#include "pico/stdlib.h"
3
#include "hardware/spi.h"
4
uint8_t mosi=19;
5
uint8_t clock=18;
6
uint8_t cs=17;
7
uint8_t miso=16;
8
uint8_t dio0=0;
9
uint8_t dio5=1;
10
11
uint8_t RegFifo = 0x00;
12
uint8_t RegOpMode = 0x01;
13
uint8_t RegFrMsb = 0x06;
14
uint8_t RegFrMid = 0x07;
15
uint8_t RegFrLsb = 0x08;
16
uint8_t RegFifoAddrPtr = 0x0D;
17
uint8_t RegFifoTxBase = 0x0E;
18
uint8_t RegFifoRxBase = 0x0F;
19
uint8_t RegFifoRxCurrent = 0x10;
20
uint8_t RegIrqFlags = 0x12;
21
uint8_t RegRxNbBytes = 0x13;
22
uint8_t RegPktSnr = 0x19;
23
uint8_t RegPktRssi = 0x1A;
24
uint8_t RegRssi = 0x1B;
25
uint8_t RegModemConfig1 = 0x1D;
26
uint8_t RegModemConfig2 = 0x1E;
27
uint8_t RegDioMapping1 = 0x40;
28
29
30
uint8_t readReg(uint8_t reg);
31
void writeReg(uint8_t reg, uint8_t msg);
32
33
void writeFifo(uint8_t * msg, int count){
34
    writeReg(RegFifoAddrPtr,readReg(RegFifoTxBase));
35
    uint8_t package[count +1];
36
    package[0]=RegFifo | 0x80;
37
    for( int i=0;i<count;i++){
38
        package[i+1]=msg[i+1];
39
    }
40
    gpio_put(cs,0);
41
    spi_write_blocking(spi0,package, count+1);
42
    sleep_ms(10);
43
    gpio_put(cs,1);
44
}
45
46
void readFifo(uint8_t *buf, int count){
47
    gpio_put(cs,0);
48
    writeReg(RegFifoAddrPtr,readReg(RegFifoRxCurrent));
49
    spi_write_blocking(spi0,&RegFifo,1);
50
    spi_read_blocking(spi0,0,buf,count);
51
    sleep_ms(10);
52
    gpio_put(cs,1);
53
}
54
55
uint8_t readReg(uint8_t reg){
56
    uint8_t result;
57
    gpio_put(cs,0);
58
    spi_write_blocking(spi0,&reg,1);
59
    spi_read_blocking(spi0,0,&result, 1);
60
    sleep_ms(10);
61
    gpio_put(cs,1);
62
    return result;
63
}
64
65
void writeReg(uint8_t reg, uint8_t msg){
66
    uint8_t package[2];
67
    package[0]=reg | 0x80;
68
    package[1]=msg;
69
    gpio_put(cs,0);
70
    spi_write_blocking(spi0,package, 2);
71
    sleep_ms(10);
72
    gpio_put(cs,1);
73
74
}
75
76
void setMode(uint8_t mode){
77
78
    if(mode<8){
79
        writeReg(RegOpMode, 0x00);
80
        writeReg(RegOpMode,0x80 | mode);
81
    }
82
    else{
83
        printf("invalid mode\n");
84
    }
85
}
86
87
void loraInit(){
88
    gpio_init(cs);
89
    gpio_set_dir(cs,1);
90
    gpio_put(cs,1);
91
    gpio_init(dio0);
92
    gpio_set_dir(dio0,0);
93
    gpio_init(dio5);
94
    gpio_set_dir(dio5,0);
95
96
    spi_init(spi0,200000000);
97
    spi_set_format(spi0,8,0,0,SPI_MSB_FIRST);
98
    
99
    gpio_set_function(clock,GPIO_FUNC_SPI);
100
    gpio_set_function(mosi,GPIO_FUNC_SPI);
101
    gpio_set_function(miso,GPIO_FUNC_SPI);
102
103
    
104
    writeReg(RegOpMode, 0x00);
105
    writeReg(RegOpMode,0x85);
106
    writeReg(RegFrMsb,0xD9);
107
    writeReg(RegFrMid,0x40);
108
109
}
110
int main() {
111
    stdio_init_all();
112
    loraInit();
113
 //   setMode(6);
114
    
115
    while(1){
116
       if(gpio_get(dio0)){
117
           uint8_t msgSize = readReg(RegRxNbBytes);//read size of recieved package
118
           uint8_t buf[msgSize];
119
           readFifo(buf, msgSize);
120
           writeReg(RegIrqFlags,0xFF);
121
           printf("recieved message:\n");
122
           for(int i=0;i<msgSize; i++){
123
               printf("%d ",buf[i]);
124
           }
125
           printf("\n");
126
       }      
127
       printf("%x \n",readReg(RegOpMode));
128
       
129
       sleep_ms(500);
130
    }
131
}

Ich hoffe mir kann jemand helfen, ich bin mit meinem Latein ein wenig am 
Ende.

: Bearbeitet durch User
von Christian S. (roehrenvorheizer)


Lesenswert?

Hallo,

David P. schrieb:
> und
> "entwickle" das ganze deshalb selbst.
sehr lobenswert

David P. schrieb:
> und habe die Infos
> alle aus dem Datenblatt.
geniale Idee

Ich finde es immer wieder als Zeugnis überragender Fähigkeiten, wenn 
jemand entwickeln kann, ohne Kommentare hinter die Zeilen zu schreiben 
und alle Bedeutungen der Einstellungen im Kopf korrekt parat haben kann.

was bewirkt eigentlich da die 8 in der zweiten Zeile?
Du möchstest anscheinend LoRa-mode einstellen und dies kommt zwei Mal im 
Code vor. Es gibt einen magischen Satz zu diesem Bit, der hier 
Einschränkungen bringt:
"0  FSK/OOK Mode
1 LoRa Mode
This bit can be modified only in Sleep mode. A write operation on
other device modes is ignored"
    writeReg(RegOpMode, 0x00);
    writeReg(RegOpMode,0x85);

Dabla Tabel 42
6-5 ModulationType rw 0x00


Und hast Du den hierauf folgenden Text beachtet?
4.4. LoRa Mode Register Map

mfg

von David P. (devryd)


Lesenswert?

Christian S. schrieb:
> "0  FSK/OOK Mode
> 1 LoRa Mode
> This bit can be modified only in Sleep mode. A write operation on
> other device modes is ignored"

ah, das muss ich überlesen haben, danke

ich weiß dass ich an meinen kommentaren arbeiten muss, tut mir leid

von David P. (devryd)


Lesenswert?

Nur damit ich das richtig verstanden habe:
ich schreibe 0x00 an das register für sleep
ich schreibe 0x80 an das register für lora mode
ich setze den gewünschten modus beispielsweise 0x85 für Rx.

von Christian S. (roehrenvorheizer)


Lesenswert?

David P. schrieb:
> ich setze den gewünschten modus beispielsweise 0x85 für Rx.

Ja, im Prinzip sehe ich das auch so. Für den Modus müßte sogar 0x05 
ausreichen, da zuvor separat umgeschaltet wurde. Eine Lesestelle, wonach 
zum Umschalten noch eine Wartezeit einzuhalten wäre, habe ich nirgends 
gefunden.

Allerdings habe ich das Gerät nicht da, sondern kann nur nach Datenblatt 
angaben machen. Was da fehlt oder ungenau beschrieben ist, kann man nur 
anhand funktionierender Programme anderer Leute heraus arbeiten.

mfg

von Helmut -. (dc3yc)


Lesenswert?

Warum verwendest du die RadioLib von jgromes nicht zur Unterstützung? 
Die kann sicher fast alles, was du brauchst und geht auch für den 
RP2040. Siehe https://github.com/jgromes/RadioLib

von temp (Gast)


Lesenswert?

Helmut -. schrieb:
> Warum verwendest du die RadioLib von jgromes nicht zur
> Unterstützung?
> Die kann sicher fast alles, was du brauchst und geht auch für den
> RP2040. Siehe https://github.com/jgromes/RadioLib

Ich kann den David nur ermutigen weiter zu machen und keine Lib zu 
verwenden.  Es ist ja nun kein Hexenwerk per SPI ein paar Register zu 
beschreiben. Und wenn es nicht wie bei der RadioLib eine eierlegende 
Wollmilchsau werden soll, reicht da eine simple Tabelle und eine kleine 
Schleife. Es hat dann den großen Vorteil, dass man auch versteht was man 
am Ende gemacht hat. Durch die  genannte Lib muss man auch erst mal 
durchsteigen, die Doku ist nicht mehr als eine Aufzählung der Funktionen 
und ihrer Parameter. Nichts davon versteht man, wenn man das Datenblatt 
der verwendeten Chips nicht gelesen hat. Und wenn man es hat, braucht 
man keine Lib. Und wenn was wichtiges fehlt (OOK z.B. bei RFM95) bastelt 
man das dann doch selbst.

von David P. (devryd)


Lesenswert?

Ich habe die verschiedenen Modi mitlerweile auch zum laufen bekommen, 
glaube aber, dass ich eines der Module zerstört habe. ich kann beide als 
sende Modul setzen und bekomme auch je eine Bestätigung, dass ein Paket 
gesendet wurde, aber ich empfange nichts. Da ich die Module vorher 
schonmal versucht habe zu benutzen, ist es durchaus möglich, dass dabei 
etwas kaputt gegangen ist. Ich habe Ersatz bestellt und werde weiter 
schauen, wenn die neuen Module da sind

Vielen Dank für eure Hilfe

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.