Avr net io

emilio20

Level-1
Beiträge
835
Reaktionspunkte
20
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo es gab im Forum mal eine Thema AVR NET IO. leider finde ich nichts mehr über die suche.

Ich wollte das AVR NET io an meine S7 Testen. Leider ohne Erfolg.

Meine AVR NET IO hat die ip 192.168.178.40. Ich habe die IP im OB1 eingegeben. Dann habe ich das Projekt auf dem PLCSIM laufen lassen. Habe aber keine Kommunikation zum AVR NET IO erhalten.

Liegt es daran das ich das Projekt nicht auf meine 315 PN gespielt habe oder kann es mit der IP des Routers zusammenhängen?
 
Ich glaube PLCSIM ist nicht Netzwerkfähig ;)

Grüße

Marcel

Da solltest du einmal Thomas fragen, der kann dazu etwas erzählen.:D

Ich kann über Netz zwischen verschiedenen VM's, also HMI da und PLCSIM dort zugreifen.
Ja, es funktioniert mit der Erweiterung von ThomasV2.1.


bike

Ups, da war jemand schneller ;-)
 
Wie schon richtig geschrieben hat Plcsim von Hause aus keine Netzwerkverbindung. Mit meiner Erweiterung ist auch nur S7-Kommunikation möglich. Projektierte Verbindungen in Netpro werden also nicht unterstützt.

Damit das mit Plcsim und Nettoplcsim funktioniert, müsstest du also auf deinem AVR zumindest teilweise das S7-Protokoll in Software umsetzen, oder eine Bibliothek wie libnodave verwenden welche entsprechende Funktionen beinhaltet.

Da das für einen kleinen AVR aber schon eine große Aufgabe bedeutet, gehe ich mal davon aus dass du vorhattest Daten über einen reinen TCP-Strom mit der SPS auszutauschen, und in der SPS dann mit AG_SEND/AG_RECEIVE dieses handzuhaben. Das kannst du aber leider in keiner Weise mit Plcsim testen.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo habe grade was im netz gefunden

http://hartwig-elektronik.de/shop/a...html?shop_param=cid=80&aid=50000%2000%200003&

http://www.mikrocontroller.net/topic/264091

Es gibt ein SPS Programm das mit dem AVR net io betrieben werden kann.
http://www.sps-forum.de/showthread.php/38059-Temperaturen-g%FCnstig-messern?p=280753#post280753

Hat jemand die Erfahrung das aktuelle Programm auf das neue AVR net IO 2 umzuschreiben ? Wäre super was man damit alles im Haus machen könnte für keines Geld ?
 
Zuletzt bearbeitet:
ich hab libnodave zumindest mal erfolgreich mit dem gcc avr compiliert, aber mit einem seriellen interface! getestet hab ich das ganze aber nie! ob auch ethernet mit dem net io gehen würde? kp, aber mann müsste bestimmt den socket auf und abbau, sowie das senden der daten neu entwickeln, oder gibt es dafür eine lib, das man mit dem net io die normalen socket befehle verwenden kann?
 
Hallo hab mal ein paar fragen zu diesem Programm siehe rot markierte stellen

Code:
FUNCTION_BLOCK NET_IO
TITLE = 'NET-IO'
NAME    : NET_IO
FAMILY  : ''
AUTHOR  : dalbi
VERSION : '1.0'

VAR_INPUT
  CONNECT : BOOL;
  ID : WORD;  
  DEV_ID : BYTE;  
  IP_ADDR1 : INT;  
  IP_ADDR2 : INT;  
  IP_ADDR3 : INT;  
  IP_ADDR4 : INT;  
END_VAR
VAR_IN_OUT
  NET_IO : UDT_NET_IO;
END_VAR  
VAR_OUTPUT
  CONNECTED : BOOL;
END_VAR    
VAR_TEMP
  TempPointer : ANY;
  AnyPointer AT TempPointer : STRUCT
    BYTE0 : BYTE; //10h
    TYP : BYTE;   //Daten/Parametertyp
    ANZ : WORD;   //Länge
    DBNr : WORD;  //DB-Nummer
    BZ : DWORD;   //Bereichszeiger
  END_STRUCT;
  i : INT;
  BCD_Code : DWORD;
END_VAR
VAR
  TCON : TCON;
  TSEND : TSEND;
  TRCV : TRCV;
  TDISCON : TDISCON;
  TCON_PAR : TCON_PAR;
  TON_CON : TON;
  TON_SEND : TOF;
  PulsePosConn : BOOL;   
  PulseNegConn : BOOL;   
  EdgeFlagPos : BOOL;
  EdgeFlagNeg : BOOL;
  Count : INT;
  RcvData : ARRAY[0..23] OF CHAR;
  GETPORT : ARRAY [0..10] OF CHAR := 'G','E','T','P','O','R','T',' ','X', '$L', '$R';  
  GETADC : ARRAY [0..9] OF CHAR := 'G','E','T','A','D','C',' ','X', '$L', '$R';  
  SETPORT : ARRAY [0..12] OF CHAR := 'S','E','T','P','O','R','T',' ','X','.','Y', '$L', '$R';  
  GETSTATUS : ARRAY [0..10] OF CHAR := 'G','E','T','S','T','A','T','U','S', '$L', '$R';  
END_VAR

BEGIN

(*********************************************************)    
(* Get the positive pulse                                *)
(*********************************************************)    

  PulsePosConn := CONNECT AND NOT EdgeFlagPos;
  EdgeFlagPos := CONNECT;

(*********************************************************)    
(* Get the negative pulse                                *)
(*********************************************************)    

  PulseNegConn := NOT CONNECT AND EdgeFlagNeg;
  EdgeFlagNeg := CONNECT;

(*********************************************************)    
(* Set ID of the specified connection                    *)
(*********************************************************)

  TCON_PAR.id := ID;
  TCON_PAR.local_device_id := DEV_ID;

(*********************************************************)    
(* Set IP address values                                 *)
(*********************************************************)    

  TCON_PAR.rem_staddr[1] := WORD_TO_BYTE(INT_TO_WORD(IP_ADDR1));
  TCON_PAR.rem_staddr[2] := WORD_TO_BYTE(INT_TO_WORD(IP_ADDR2));
  TCON_PAR.rem_staddr[3] := WORD_TO_BYTE(INT_TO_WORD(IP_ADDR3));
  TCON_PAR.rem_staddr[4] := WORD_TO_BYTE(INT_TO_WORD(IP_ADDR4));

(*********************************************************)    
(* Establish connection                                  *)
(*********************************************************)    

  IF PulsePosConn THEN
    TCON.REQ := TRUE;
  END_IF;  
  
  TCON(REQ     := TCON.REQ,
       ID      := TCON_PAR.id,
       CONNECT := TCON_PAR);
      
  IF TCON.DONE THEN
    CONNECTED := TRUE;
    TCON.REQ := FALSE;
  END_IF;
  
  TON_CON(IN := CONNECTED,
          PT := T#2s); 
   
(*********************************************************)
(*********************************************************)

  CASE Count OF
    1..8:   SETPORT[8] := INT_TO_CHAR(Count [COLOR=#ff0000]+ 48[/COLOR]);[COLOR=#ff0000] // was hat es mit den 48 aufsich ?[/COLOR]
            SETPORT[10] := INT_TO_CHAR(BOOL_TO_INT(NET_IO.DigiOut[Count]) [COLOR=#ff0000]+ 48[/COLOR]);
            TempPointer := SETPORT;
    9..12:  GETPORT[8] := INT_TO_CHAR(Count - 8 [COLOR=#ff0000]+ 48[/COLOR]);
            TempPointer := GETPORT;
    13..16: GETADC[7] := INT_TO_CHAR(Count - 12 [COLOR=#ff0000]+ 48[/COLOR]);
            TempPointer := GETADC;
    17:     TempPointer := GETSTATUS;
  ELSE
    Count := 1;
    TempPointer := GETSTATUS;
  END_CASE;      

(*********************************************************)
(* Send data over existing connection                    *)    
(*********************************************************) 

  TSEND.LEN := WORD_TO_INT(AnyPointer.ANZ);

  IF TON_CON.Q THEN
    
    TON_SEND(IN := NOT TSEND.REQ,
             PT := T#50ms);
              
    TSEND.REQ := TON_SEND.Q; 
    
    TSEND(REQ  := TSEND.REQ,
          ID   := TCON_PAR.id,
          LEN  := TSEND.LEN, 
          DATA := TempPointer);

  END_IF; 

(*********************************************************)
(* Receive data over existing connection                 *)    
(*********************************************************)    

  IF CONNECTED THEN

    TRCV(EN_R := TRUE,
         ID   := TCON_PAR.ID,
         LEN  :=[COLOR=#ff0000] TRCV.LEN,[/COLOR] [COLOR=#ff0000] // woher weiß mann wieviele BYTE ankommen ? [/COLOR]
         DATA := RcvData); 
     
  END_IF;
  
  BCD_Code := 0;
  
  [COLOR=#000000]IF TRCV.NDR THEN [/COLOR]
    CASE Count OF
      1..8:   IF RcvData[0] = 'A' AND RcvData[1] = 'C' AND RcvData[[COLOR=#ff0000]1[/COLOR]] = 'K' THEN  [COLOR=#ff0000]//??? musste das nicht 2 heißen ?[/COLOR]
                ;
              END_IF;  
      9..12:  IF RcvData[0] = '0' THEN
                NET_IO.DigiIn[Count-8] := FALSE;
              ELSIF RcvData[0] = '1' THEN
                NET_IO.DigiIn[Count-8] := TRUE;
              END_IF;    
      13..16: IF CHAR_TO_INT(RcvData[0]) >= 48 AND CHAR_TO_INT(RcvData[0]) <= 57 THEN
                BCD_Code := WORD_TO_DWORD(INT_TO_BCD(CHAR_TO_INT(RcvData[0]) - 48)); 
              END_IF;
              IF CHAR_TO_INT(RcvData[1]) >= 48 AND CHAR_TO_INT(RcvData[1]) <= 57 THEN
                BCD_Code := SHL(IN:=BCD_Code, N:=4);
                BCD_Code := BCD_Code OR WORD_TO_DWORD(INT_TO_BCD(CHAR_TO_INT(RcvData[1]) - 48));
              END_IF;  
              IF CHAR_TO_INT(RcvData[2]) >= 48 AND CHAR_TO_INT(RcvData[2]) <= 57 THEN
                BCD_Code := SHL(IN:=BCD_Code, N:=4);
                BCD_Code := BCD_Code OR WORD_TO_DWORD(INT_TO_BCD(CHAR_TO_INT(RcvData[2]) - 48));
              END_IF;  
              IF CHAR_TO_INT(RcvData[3]) >= 48 AND CHAR_TO_INT(RcvData[3]) <= 57 THEN
                BCD_Code := SHL(IN:=BCD_Code, N:=4);
                BCD_Code := BCD_Code OR WORD_TO_DWORD(INT_TO_BCD(CHAR_TO_INT(RcvData[3]) - 48));
              END_IF;  
              NET_IO.AnaIn[Count-12] := DINT_TO_INT(DWORD_BCD_TO_DINT(BCD_Code));
      17:     IF RcvData[0] = 'S' THEN
                FOR i := 1 TO 8 DO
                  NET_IO.StatusOut[i] := INT_TO_BOOL(CHAR_TO_INT(RcvData[9-i]) - 48);
                END_FOR;  
              END_IF;
    END_CASE;
    [COLOR=#000000]Count := Count + 1;  [/COLOR]
    
    FOR i := 0 TO 23 DO
      RcvData[i] := ' ';
    END_FOR;      
  END_IF;
  
(*********************************************************)    
(* Existing connection end                               *)
(*********************************************************)    

  IF PulseNegConn AND CONNECTED THEN
    TDISCON.REQ := TRUE;
  END_IF;  
  
  TDISCON(REQ := TDISCON.REQ,
          ID  := TCON_PAR.id); 
      
  IF TDISCON.DONE THEN
    CONNECTED := FALSE;
    TDISCON.REQ := FALSE;
    Count := 1;
  END_IF;

END_FUNCTION_BLOCK
 
Zuletzt bearbeitet:
Ok und die anderen sachen ?

Wollte sowas für ein Arduino anpassen . Hier muss ich aber erst den CODe am Arduino erstellen.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo Dalbi
das kenne ich. Hab eine Komunikation mit einem Arduino erstellt. Wollte jetzt ich E/A und die Analogen eingänge noch abfragen. hierzu wollte ich dein Programm abändern.

Könntest du mir dei rot markierten stellen erklären. Das mit den 48 hat sich erledigt.

Wie gibts du die große der empfangenen byts an ?


LEN := TRCV.LEN, // woher weiß mann wieviele BYTE ankommen ?

mann muss doch im vorfeld sagen vieviel BYTE's empfangen werden oder ?

OK habs glaube ich verstanden du schreibs die empfangene datenlänge in LEN.
 
Zuletzt bearbeitet:
Nein. NDR ist TRUE es liegen neue Daten vor.
Die Anzahl der empfangenen Bytes erkennt man dann über LEN.

Voraussetzung der Empfangspuffer ist groß genug.

Hab ja auch einen Arduino hier. Vielleicht probiere ich das auch mal aus.

Gruss Daniel
 
Wäre super.
Ich beschreibe dir mal mein Aktuelle Programm.
Ich Sende einen Array of CHAR mit 32Byte ans Arduino. Dort zerlegen ich den CHAR in 2x 16 CHAR und schreibe den TEXT auf einen 2x16 Zeichen Display.
Das Arduino Sendet die empfangenden Daten wieder an die SPS, 32 CHAR. In der SPS vergleiche ich die empfangenen Daten mit den gesendeten Daten. Wenn dies ungleich sind wird gesendet wenn gleich wird nicht gesendet.

Ich hatte das Problem das ich immer 32Byte Senden musste(Text musste mit leerzeichen gefüllt werden.) annstonsten haben meine empfangenden Daten nicht mit meinen gesendeten übereingestimmt.

Kann aber auch an dem Arduino Programm liegen.

Code:
Arduino Programm

#include <SPI.h>
#include <Ethernet.h>
#include <Wire.h> 
#include <LiquidCrystal_I2C.h>

    LiquidCrystal_I2C lcd(0x3F,16,2);


byte mac[] = { 
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192,168,178, 50);
IPAddress gateway(192,168,178, 1);
IPAddress subnet(255, 255, 255, 0);



EthernetServer server(2500);
boolean alreadyConnected = false; 

  char thisChar[33];
  char thisChar1[16];
  char thisChar2[16];
  
  
  int i;

void setup() {
  
  lcd.init();
   
    
  lcd.backlight();
  lcd.setCursor(0,0);
  lcd.print("Starten");
  lcd.setCursor(0,1);
  lcd.print("System");
  delay( 3000);
  lcd.clear();
  
  
  // initialize the ethernet device
  Ethernet.begin(mac, ip, gateway, subnet);
  // start listening for clients
  server.begin();
 // Open serial communications and wait for port to open:
  Serial.begin(9600);
   while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }


  Serial.print("Chat server address:");
  Serial.println(Ethernet.localIP());
}

void loop() {
  // wait for a new client:
  EthernetClient client = server.available();

  
  if (client) {
    if (!alreadyConnected) {
      // clead out the input buffer:
      client.flush();    
      Serial.println("We have a new client");
      //client.println(Verbindung);
      //server.write(Verbindung); 
      alreadyConnected = true;
      lcd.clear();
      lcd.setCursor(0,0);
      lcd.print("  Verbunden  ");
      delay( 5000);
      lcd.clear();
            
      
    } 
    
    if (client.available() > 0) {
       for (i = 0; i < 32; i++) {
       // read the bytes incoming from the client:
       thisChar[i] = client.read();
      }
     // Backlight aus  
       if (strcmp (thisChar, "noBacklight                     ") == 0){
          lcd.noBacklight();
          Serial.println("noBacklight");
          delay(500);}
          else{
          lcd.backlight();
      }
      
      // echo the bytes back to the client:
      server.write(thisChar);
      // echo the bytes to the server as well:
      Serial.write(thisChar);
      
      for (i =0;i <17;  i++){
        thisChar1[i]=thisChar[i];
            
      }
           
      
      for (i =17;i <33;  i++){
        thisChar2[i-16]=thisChar[i];
      
      }
      lcd.setCursor(0,0);
      lcd.print(thisChar1);
      lcd.setCursor(0,1);
      lcd.print(thisChar2);
      
      delay( 1);
    }
  }
    
  
}
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo
dalbi

habe mir mal das ganze angeschaut ich bin nicht fit genug in C++ um den Code vom AVR net io am Arduino nachzubilden. Hast du erfahrung und lust dir das mal anzuschauen ? Wäre super wenn das gehen würde.
 
Hallo,

ich bin im Besitz einer S7 315-2 DP und CP343-1. Ist es auch mit diesen Baugruppen möglich
mit dem AVR NET-IO zu kommunizieren?
Die FB63 bis FB65 werden ja in dieser CPU nicht unterstützt.
 
Hi emilio20,

Code:
#include <SPI.h>
#include <Ethernet.h>
#include <Wire.h> 
#include <LiquidCrystal_I2C.h>


LiquidCrystal_I2C lcd(0x38,20,4);


byte mac[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED}; // MAC-Adresse
byte ip[] = {192, 168, 0, 98}; // IP-Adresse
EthernetServer server(1000);   // Port
 
String readBuffer;


 
void setup()
{
  Serial.begin(9600);


  lcd.init();
  lcd.backlight();
  lcd.setCursor(0,0);
  lcd.print("dalbi");
  lcd.setCursor(0,1);
  lcd.print("SPS <-> Arduino");
  
  Ethernet.begin(mac, ip);
  server.begin();
  delay(1000);
}
 
void loop() {
  EthernetClient client = server.available();
  if (client) {
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        readBuffer = readBuffer + c;
        if (c == '\n') {    // warten auf new line
          // clearlcd <= Löscht alle Zeichen          
          if(readBuffer.startsWith("clearlcd")) {
            lcd.clear();
            client.println("ACK");
          }
          // writelcd 1.Testtext <= Schreibt Testtext in Zeile 1
          // writelcd 2.Testtext <= Schreibt Testtext in Zeile 2
          if(readBuffer.startsWith("writelcd")) {
            lcd.setCursor(0, readBuffer[9]-49);  // Zeile 1-x
            lcd.print(readBuffer.substring(11, readBuffer.length()-2));
            client.println("ACK");
          }
          // backllcd 1 <= Schaltet die Hintergrundbeleuchtung ein
          // backllcd 0 <= Schaltet die Hintergrungbeleuchtung aus
          if(readBuffer.startsWith("backllcd")) {
            if ((readBuffer[9]-48) == 1) {
              lcd.setBacklight(0);
            } else {
              lcd.backlight();
            }
            client.println("ACK");
          }          
          readBuffer = "";
        }
      }
    }
  }
  client.stop();
}

Die Ethernetparameter und das LCD musst halt entsprechend anpassen.

Folgendes geht jetzt:

clearlcd <- Löscht alle Zeichen
writelcd 1.Testtext <- Schreibt Testtext in die erste Zeile
backllcd 1 <- Schaltet die Hintergrundbeleuchtung ein
backllcd 0 <- Schaltet die Hintergrundbeleuchtung aus

Beim Senden von der SPS ist darauf zu achten das die letzten Zeichen \r\n sind.
Als quittierung vom Arduino zur SPS wird ACK gesendet.

Gruss Daniel
 
Zuletzt bearbeitet:
Zurück
Oben