RS485 mit Blankem MAX485 Chip

Wenn du nun deine RE/DE Verkabelung richtig gestellt hast, könntest ja mal meinen code aus #4 testen (Pins anpassen!).

Das MUSS funktionieren.

1 Like

Au Manien uraltem Telefon kann das nicht so gut sehen, jetzt am Laptop schon.
Sorry.

ES LÄUFT!!!!

es lag wahrscheinlich wirklich an dem vergessenen.

pinMode(2,OUTPUT);

im Setup

EDIT: jetzt kommt dann der zweite Test mit zwei teilnehmernXD

Ist jemandem bekannt das die MAX485 relativ schnell die Hufe hoch machen?

ich heb hier 3 Bausteine mit denen nichts mehr geht. mit den andern 7 läufts. Hab ich gestern vllt. zerstört. Sind die beim Ein- und Ausbauen iwi empfindlich? oder lag das vllt. an den fehlenden Abblockkondensatoren?

EDIT: zu früh gefreut. Nachdem ich es jetzt eine weile Stabil laufen hatte macht es jetzt wider Probleme. Allerdings habe ich noch nicht rausgefunden warum, da die Probleme unspezifisch sind. es scheint als ob im Buffer der MAX485 noch irgendwelches sinnloses zeug rumliegt das mir den ganzen Ablauf zerlegt.

Ist das grundsätzlich möglich? Das durch das auf und abbauen Strom an aus sich da iwi was verhaspelt?

EDIT: Jetzt geht es wider... irgendwie... aber... naja guck selbst

Ausgabe ArduinoC (empfängt wert und gibt zurück)

My ID is: 2 readID= 0 Value= 10010110
My ID is: 2 readID= 1 Value= 10010110
My ID is: 2 readID= 124 Value= 1
My ID is: 2 readID= 150 Value= 1
My ID is: 2 readID= 2 Value= 10010110
1
SET VALVES to 10010110
I return ID: 2 and value: 10010110
My ID is: 2 readID= 4 Value= 10010110
My ID is: 2 readID= 5 Value= 10010110
My ID is: 2 readID= 6 Value= 10010110
My ID is: 2 readID= 7 Value= 10010110

Ausgabe ArduinoB (empfängt wert und gibt zurück)

My ID is: 1 readID= 0 Value= 10010110
My ID is: 1 readID= 1 Value= 10010110
1
SET VALVES to 10010110
I return ID: 1 and value: 10010110
My ID is: 1 readID= 255 Value= 1111100
My ID is: 1 readID= 2 Value= 10010110
My ID is: 1 readID= 3 Value= 10010110
My ID is: 1 readID= 4 Value= 10010110
My ID is: 1 readID= 5 Value= 10010110
My ID is: 1 readID= 6 Value= 10010110
My ID is: 1 readID= 7 Value= 10010110

und beim ArduinoA

I Send 10010110 To ID 0
0No Device
I Send 10010110 To ID 1
0Correct Return Value
I Send 10010110 To ID 2
0Correct Return Value
I Send 10010110 To ID 3
0No Device
I Send 10010110 To ID 4
0No Device
I Send 10010110 To ID 5
0No Device
I Send 10010110 To ID 6
0No Device
I Send 10010110 To ID 7
0No Device

was mich wundert ist das bei den Empfängern immer mal ein oder zwei Bytes ankommen die nie gesendet wurden (also zumindest nicht absichtlich)

Aber da liest du immer nur ein Byte aus richtig? Wie würde denn der Code mit Serial.readBytesUntil(‚|‘,data,2) aussehen? Ich habe dafür das SerialAviable() weggelassen weil mir das iwi immer die Kommunikation zerlegt hat

ich lese byte weise ein bis der Endmarker erkannt wird

braucht man nicht. Wenn noch nicht gemacht, geh das Tutorial Serial Input Basics durch - komplett.

Ok dann guck ich mir das nochmal an danke

Ich verstehe den code nicht.

Das Ergebnis ist ja das Pingpong mit den zahlen gewesen wenn ich mich recht entsinne.

aber der Loop sendet doch garnichts sondern nur ein mal im Setup.

und was macht das check time to send?

Ich weis ja das im rs485 nur einer senden darf, ist das das warten darauf das die Leitung frei wird?

void setup() {
  Serial.begin(9600);
  mySerial.begin(9600);
  pinMode(enablePin, OUTPUT);
  transmit(dataNumber);
}

void loop() {
  recvWithEndMarker();
  checkTimeToSend();
}

du wolltest ein ping pong.

der recvWithEndMarker() wertet hereinkommende Zeichen aus und macht das so lange bis der Endmarker kommt.
Wenn der Endmarker kommt,

  • werden die bisherigen Zeichen zu einem string gemacht,
  • auf der Seriellen ausgegeben
  • und ein "timer" gestartet

Der checkTimeToSend() prüft, ob es Zeit ist etwas zu tun ist.
Und das ist eine Sekunde nach dem etwas hereingekommen ist.
Daher das previousMillis, daher das isActive flag.

Vor dem eigentlichen Senden wird die lokale dataNumber noch erhöht.
nach dem Senden wird das isActive flag wieder auf inaktiv gesetzt.
(mit der Auswirkung dass dieser Teilnehmer wieder auf eine Antwort vom anderen wartet).

Daher verstummen die Ausgaben am Bus, wenn nie etwas zurückkommt.
Andererseits wird aber durch ein Einschalten des Partners die gegenseitige Kommunikation wieder "aktiviert" - weil eben in setup() ein transmit() drinnen ist (der dann hoffentlich beim anderen ankommt).

recvWithEndMarker() und checkTimeToSend() sind zwei nebenläufige Aktivitäten, sehr weit hergeholt zwei "Tasks" die "nebeneinander" laufen.

Man hätte das auch ohne timer machen können, aber dann wird das ganze halt so schnell das man wieder keine Zusammenhänge erkennt. Und delays() meide ich.

Daher ohne Pong kein Ping.

Ich habe es auf dem UNO jetzt fehlerfrei zum laufen gebracht, und wollte das ganze jetzt auf meinen eigentlich ausgewählten Chip Tiny2313 überschreiben.

Leider bekomme ich einen Compiler Error

Sketch too big; see https://support.arduino.cc/hc/en-us/articles/360013825179 for tips on reducing it.
Sketch uses 8150 bytes (198%) of program storage space. Maximum is 4096 bytes.
Global variables use 433 bytes (169%) of dynamic memory, leaving -177 bytes for local variables. Maximum is 256 bytes.
text section exceeds available space in board

Compilation error: text section exceeds available space in board

Nun die Frage, warum ist mein Sketch so Groß liegt das an den LIBs? und kann man da was machen um den zu komprimieren oder bleibt da nur n anderer Chip als Option?

Hier nochmal der Code

#include <SoftwareSerial.h>
#include <Adafruit_MCP23X17.h>

#define Pin_watchdog 8
#define RX2 6
#define TX2 7
#define S0 8
#define S1 9
#define S2 10
#define Out_close 11
#define Out_Open 12
#define SDA 14
#define SCL 16

Adafruit_MCP23X17 mcpONOFF;
Adafruit_MCP23X17 mcpLED;
byte MCPADR=0x20;
byte MCPADR2=0x21;
SoftwareSerial mySerial(RX2,TX2);
// RX on digital pin 10
// TX on digital pin 11
String sendMessage;
String receivedMessage;
uint8_t ID    =0;
int     readID=0;
int     value =0;
byte    data [2];
void setup() {
  pinMode(2, OUTPUT);
  pinMode(7,INPUT);
  pinMode(6,INPUT);
  pinMode(5,INPUT);

  Serial.begin(9600);
  mySerial.begin(9600);
 
     if (!mcpONOFF.begin_I2C(MCPADR)) {
    Serial.println("Error.");
    while (1);{ Serial.print("Hänge Fest");
      }}
        if (!mcpLED.begin_I2C(MCPADR2)) {
    Serial.println("Error.");
    while (1);{ Serial.print("Hänge Fest");
      }}
  for(int i=0;i<16;i++){
  Serial.println("Before mcp.pinmode");
    mcpONOFF.pinMode(i, OUTPUT);
    Serial.print("PinMode OUTPUT FOR PIN");  Serial.println(i);
  }
  for(int i=0;i<16;i++){
  Serial.println("Before mcp.pinmode");
    mcpLED.pinMode(i, OUTPUT);
    Serial.print("PinMode OUTPUT FOR PIN");  Serial.println(i);
  }




  Serial.println("Arduino1 Start RS485 RT Test");
  digitalWrite(2,LOW);  
  }

void loop() {

  ID =(digitalRead(5)<<2);
  ID +=(digitalRead(6)<<1);
  ID +=(digitalRead(7));
    
     digitalWrite(2,LOW);
      while(digitalRead(2)){}
   
    mySerial.readBytesUntil('MACK',data,2);


    if(readID!=data[0]){
       
      Serial.print("My ID is: ");Serial.print(ID);
    readID=data[0];
    value=data[1];
   // Serial.print(" readID= ");Serial.print (readID);
    //Serial.print(" Value= ");Serial.println(value,BIN);
  if(readID==ID){
digitalWrite(2,HIGH);
while(!digitalRead(2)){
//Serial.println(digitalRead(2));

};
//Serial.println(digitalRead(2));
   Serial.print("SET VALVES to ");Serial.println(value,BIN);
        
        mySerial.write(readID);
        mySerial.write(value);
        mySerial.write('SACK');
       
        
    Serial.print("I return ID: ");Serial.print(readID);Serial.print(" and value: ");Serial.println(value,BIN);
  }
  }

}

void SetValve (byte Value){
for(int i=0;i<7;i++){
  if ((value  & (1 << i))){
                            mcpONOFF.digitalWrite(i,HIGH);
                            delay(50);
                            mcpONOFF.digitalWrite(i,LOW);
                            mcpLED.digitalWrite(i,HIGH);
                            mcpLED.digitalWrite(i+8,LOW);
                            Serial.print("Valve at ");Serial.print(i);Serial.println(" was HIGH");
                           }
  else                     {
                            mcpONOFF.digitalWrite(i+8,HIGH);
                            delay(50);
                            mcpONOFF.digitalWrite(i+8,LOW);
                            mcpLED.digitalWrite(i,LOW);
                            mcpLED.digitalWrite(i+8,HIGH);
                            Serial.print("Valve at ");Serial.print(i+8);Serial.println(" was HIGH");
                           }

                    }
}


EDIT: ich habe mal die ganzen Printstrings und das Serial Auskommentiert nun sieht es so aus

Sketch uses 6124 bytes (149%) of program storage space. Maximum is 4096 bytes.
Global variables use 206 bytes (80%) of dynamic memory, leaving 50 bytes for local variables. Maximum is 256 bytes.

Die Richtung ist richtig aber immer noch zu viel

Code Sieht jetzt so aus

#include <SoftwareSerial.h>
#include <Adafruit_MCP23X17.h>

#define Pin_watchdog 8
#define Pin_RX2 6
#define Pin_TX2 7
#define Pin_S0 8
#define Pin_S1 9
#define Pin_S2 10
#define Pin_Out_close 11
#define Pin_Out_Open 12
#define Pin_SDA 14
#define Pin_SCL 16

Adafruit_MCP23X17 mcpONOFF;
Adafruit_MCP23X17 mcpLED;
byte MCPADR=0x20;
byte MCPADR2=0x21;
SoftwareSerial mySerial(Pin_RX2,Pin_TX2);

uint8_t     ID        =0;
uint8_t     readID    =0;
uint8_t     value     =0;
byte        data [2]    ; 
void setup() {
  pinMode(2,OUTPUT);
  pinMode(7,INPUT);
  pinMode(6,INPUT);
  pinMode(5,INPUT);

  //Serial.begin(9600);
  mySerial.begin(9600);
 
     if (!mcpONOFF.begin_I2C(MCPADR)) {
   // Serial.println("Error.");
    while (1);{ //Serial.print("Hänge Fest");
      }}
        if (!mcpLED.begin_I2C(MCPADR2)) {
   // Serial.println("Error.");
    while (1);{ //Serial.print("Hänge Fest");
      }}
  for(int i=0;i<16;i++){
 // Serial.println("Before mcp.pinmode");
    mcpONOFF.pinMode(i, OUTPUT);
    //Serial.print("PinMode OUTPUT FOR PIN");  Serial.println(i);
  }
  for(int i=0;i<16;i++){
  //Serial.println("Before mcp.pinmode");
    mcpLED.pinMode(i, OUTPUT);
   // Serial.print("PinMode OUTPUT FOR PIN");  Serial.println(i);
  }




  //Serial.println("Arduino1 Start RS485 RT Test");
  digitalWrite(2,LOW);  
  }

void loop() {

  ID =(digitalRead(5)<<2);
  ID +=(digitalRead(6)<<1);
  ID +=(digitalRead(7));
    
     digitalWrite(2,LOW);
      while(digitalRead(2)){}
   
    mySerial.readBytesUntil('M',data,2);


    if(readID!=data[0]){
       
      //Serial.print("My ID is: ");Serial.print(ID);
    readID=data[0];
    value=data[1];
   // Serial.print(" readID= ");Serial.print (readID);
    //Serial.print(" Value= ");Serial.println(value,BIN);
  if(readID==ID){
digitalWrite(2,HIGH);
while(!digitalRead(2)){
//Serial.println(digitalRead(2));

};
//Serial.println(digitalRead(2));
   //Serial.print("SET VALVES to ");Serial.println(value,BIN);
        
        mySerial.write(readID);
        mySerial.write(value);
        mySerial.write('S');
       
        
   // Serial.print("I return ID: ");Serial.print(readID);Serial.print(" and value: ");Serial.println(value,BIN);
  }
  }

}

void SetValve (void){
for(int i=0;i<7;i++){
  if ((value  & (1 << i))){
                            mcpONOFF.digitalWrite(i,HIGH);
                            delay(50);
                            mcpONOFF.digitalWrite(i,LOW);
                            mcpLED.digitalWrite(i,HIGH);
                            mcpLED.digitalWrite(i+8,LOW);
                            //Serial.print("Valve at ");Serial.print(i);Serial.println(" was HIGH");
                           }
  else                     {
                            mcpONOFF.digitalWrite(i+8,HIGH);
                            delay(50);
                            mcpONOFF.digitalWrite(i+8,LOW);
                            mcpLED.digitalWrite(i,LOW);
                            mcpLED.digitalWrite(i+8,HIGH);
                            //Serial.print("Valve at ");Serial.print(i+8);Serial.println(" was HIGH");
                           }

                    }
}


Versuch mall mit der
ndomx MCP23017 Arduino Library ist auf github

Vermutlich ist die I2C lib ein großer Verbraucher.
Vergleich mal mit der SPI Variante. Es gibt ja auch den MCP23S17.

1 Like