Raspberry med 1wire och modbus

Planering och tankar kring eventuella framtida projekt.
danielr112
Inlägg: 8041
Blev medlem: 18 januari 2009, 00:48:24
Ort: Alvesta, Småland

Re: Raspberry med 1wire och modbus

Inlägg av danielr112 »

Gränsen är i programvaran i pajen som sådan. Ska finnas några hårdkodade gränser och börjar man gräva på det mer så ser man att den snabbt tappar av och man får många fel från 1wire slingan.

Jag har för mig det är 8-12 eller något. Jag har kört 8 på den och på kort avstånd funkar det. (Låter det vara osagt då jag ganska snabbt bara slänge på en usb baserad/SPI baserad driver istället)

På USB slingan med aktiv matning har jag kört 100+ sensorer och 150 meter utan problem...
Användarvisningsbild
Micke_s
EF Sponsor
Inlägg: 6741
Blev medlem: 15 december 2005, 21:31:34
Ort: Malmö

Re: Raspberry med 1wire och modbus

Inlägg av Micke_s »

Titta på SQLAlchemy också, rätt så bra

https://en.m.wikipedia.org/wiki/SQLAlchemy
Användarvisningsbild
Mickecarlsson
EF Sponsor
Inlägg: 3722
Blev medlem: 15 april 2017, 18:06:15
Ort: Malmö
Kontakt:

Re: Raspberry med 1wire och modbus

Inlägg av Mickecarlsson »

Jag kör min Raspberry och 1-wire med owfs http://owfs.org/
Då sköter owfs hämtningen av alla sensorer, och du hämtar data från cache i stället.

Här är mina (gamla) minnesanteckningar hur jag satte upp min PI

Kod: Markera allt

sudo wget  -O owfs-latest.tgz http://sourceforge.net/projects/owfs/files/latest/download
tar xzvf owfs-latest.tgz
cd owfs-3.1p5/
./configure
* här fick jag nog fel, för jag hämtade hem php5 innan jag kompilerade
sudo apt-get install php5
* Kompilera, tar en bra stund
sudo make && sudo make install
* Skapa mappen för filsystemet
sudo mkdir /mnt/1wire
* Redigera fuse, kommer dock inte ihåg varför
sudo nano /etc/fuse.conf
lägg till user_allow_other längst ner i filen, spara
* Testmontera filsystemet
sudo /opt/owfs/bin/owfs -u --allow_other /mnt/1wire/
cd /mnt/1wire
ls
FormerMazda
Inlägg: 6061
Blev medlem: 27 februari 2006, 14:59:36
Ort: Tranås (Jönköping)

Re: Raspberry med 1wire och modbus

Inlägg av FormerMazda »

Owfs har jag hört talas om i dessa sammanhang. Men då kan alltså det agera som en driver till vad som nu låter mig prata modbus sen? Utan mellanlagring?

Förvisso är jag lika lost ändå just nu..
Användarvisningsbild
Mickecarlsson
EF Sponsor
Inlägg: 3722
Blev medlem: 15 april 2017, 18:06:15
Ort: Malmö
Kontakt:

Re: Raspberry med 1wire och modbus

Inlägg av Mickecarlsson »

Om du kör owfs kan du läsa av alla sensorer med 'cat':
T.ex. om du har en sensor med ID 10.974F29020800 läser du temperaturen med:
cat /mnt/1wire/10.974F29020800/temperature
I mitt fall just nu får jag svaret: 20.125, dvs, jag har en temperatur i mitt garage på 20.125 grader.

Och om du kör nyare OS i din PI kan du köra:
sudo apt-get install owfs
Då sköts installationen ganska automatiskt, dock får man sätta upp monteringspunkter och cron-job som läser dina sensorer.
FormerMazda
Inlägg: 6061
Blev medlem: 27 februari 2006, 14:59:36
Ort: Tranås (Jönköping)

Re: Raspberry med 1wire och modbus

Inlägg av FormerMazda »

Är tacksam för all hjälp, det öppnar ögonen mer och mer och gör mig sugen att pilla ihop det själv.
Men jag borde verkligen inte trilla dit i den världen också just nu.. :D

nifelheim > Var du sugen på att pilla ihop detta?
nifelheim
Den första
Inlägg: 2315
Blev medlem: 27 mars 2008, 22:31:16
Ort: stockholm

Re: Raspberry med 1wire och modbus

Inlägg av nifelheim »

"jag e' på gång" :)

paj med owfs , up and running :)

pluggat på lite olika modbus lib till pajen, strax prov installation , men


hur skapar jag en "TAG" som plockar in värdet från pajen?
Måste jag ha en "controller" vald i projektet?

tycker mätaren blev fin :)
pitest.JPG
Du har inte behörighet att öppna de filer som bifogats till detta inlägg.
FormerMazda
Inlägg: 6061
Blev medlem: 27 februari 2006, 14:59:36
Ort: Tranås (Jönköping)

Re: Raspberry med 1wire och modbus

Inlägg av FormerMazda »

Oj! Så kul!

Men ja det stämmer, du behöver en kontroller.
Lättast tror jag är om du vid uppstart av iX developer väljer en kontroller där, då sätts den upp åt dig.
Testa med Modicon - Modbus master, denna finns sen under fliken Controllers i taglistan.
Klickar du där på settings så får du välja hur den ska kommunicera, vilken "sorts" modbus mm. Börja bara med IP-adress under stations, och vilket stationsnummer du gett din paj. Port bör vara 502, ganska vanligt.
Sen skapar du en tag med nåt kul namn, och i Controller 1 skriver du i vilken modbusadress du vill läsa.

Detta är jätteenkelt beskrivet, men det är lättare att svara på frågorna när dom kommer.

Detta förutsätter ju också att din dator med iX och pajen sitter i samma nät. Testa att pinga. Testa gärna nåt enkelt läsa-modbus-program också. Typ Modscan, det använder jag mycket.
Jo, starta iX på gröna pilen, annars kommunicerar den inte.
Pen
Inlägg: 207
Blev medlem: 16 september 2006, 09:15:51
Ort: Stockholm

Re: Raspberry med 1wire och modbus

Inlägg av Pen »

Jag kör både 1wire och Modbus/TCP på min RPi. 1-wire via OWFS. Jag kompilerade ihop command-line wrappers till Modbus (Master) som sedan kan köras av alla program som kan göra "exec" eller motsvarande (alla interpreternande program antar jag). Är du intresserad av ett sådant alternativ så kan du få färdiga binärer (eller källkod av) mig.

Pen
nifelheim
Den första
Inlägg: 2315
Blev medlem: 27 mars 2008, 22:31:16
Ort: stockholm

Re: Raspberry med 1wire och modbus

Inlägg av nifelheim »

Lägg upp, lägg upp! :)

Har kört pymodbus, provade deras exempelkod och TCP servern svarade, testat med modscan, men har inte hunnit förvärva tillräckliga python kunskaper ännu. :)

edit: fast du skrev master, det är motsatsen till TCP server, inte riktigt rätt :humm:
Senast redigerad av nifelheim 31 maj 2017, 17:55:51, redigerad totalt 1 gång.
Pen
Inlägg: 207
Blev medlem: 16 september 2006, 09:15:51
Ort: Stockholm

Re: Raspberry med 1wire och modbus

Inlägg av Pen »

Kom just på att TS behöver slavprogram, eller hur? Det jag har wrappat är tyvärr bara masterprogram. Fortfarande intresserad?

Edit: Du upptäckte samma sak i din "Edit". :)

Annars är det nästan busenkelt att göra egna wrappers förutsatt att man använder libmodbus som är fritt. Kan lägga upp mina mastrar som exempelkod om så önskas. Det är inte många rader.
Senast redigerad av Pen 31 maj 2017, 18:09:01, redigerad totalt 1 gång.
Pen
Inlägg: 207
Blev medlem: 16 september 2006, 09:15:51
Ort: Stockholm

Re: Raspberry med 1wire och modbus

Inlägg av Pen »

Exempel på läsning av register:

Kod: Markera allt

// Read a single holding register (unsigned 16b value)
// Command syntax: read_holding_registers <IPAddress> <RegAddress>
// IPAddress: i.e. 192.168.0.4
// RegAddress: i.e. 1
// Note that ADAM 40001 has RegAddress 1 (in libmodbus this is address 0)
// Read value is printed
// Return value is 0 if success, 1 if fail
// Error string is printed on error (this might be unwanted)

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>

#include <modbus/modbus.h>

#define              PORT 502
#define SLAVE_ID     0x01


int main(int argc, char **argv)
{
    int      t;
    int      i;
    int      ret;                      // Error code (success = 1)
    char     *ip_address;              // Device IP address
    int      start_addr;               // Register or Coil address
    uint16_t dest[1];                  // Read value
    modbus_t *mb;           	       // Opaque object data

    if (argc != 3)
    {
       printf("ERROR Syntax error\n");
       exit(1);
    };

    ip_address = argv[1];
    start_addr = (int)atoi(argv[2])-1;  // Libmodbus uses 0 numbering

    mb = modbus_new_tcp(ip_address, PORT);

/*        modbus_set_debug(mb, TRUE);*/
      
    for (i=0; i<10; i++)    // Retry on communication error (occurs frequently on Adam)
    {
       if (modbus_connect(mb) != -1)
       {
          t = usleep(20000); 
          ret = modbus_read_registers(mb, start_addr, 1, dest);
          modbus_close(mb);
          if (ret != -1) break;	
          t = usleep(100000);
       }
       else 
       {
          ret = -1;
          modbus_close(mb);
          break;
       }
       
    }

    if (ret == -1) printf("ERROR Acces failed, Errno %i\n", errno);
    else printf("%i", dest[0]);

    modbus_free(mb);

    return 0;
}
Pen
Inlägg: 207
Blev medlem: 16 september 2006, 09:15:51
Ort: Stockholm

Re: Raspberry med 1wire och modbus

Inlägg av Pen »

Det är förstås lite klurigare (osnyggare) att göra kommando-wrappers för slavar. Man får då köra ett kommando som hänger sig och inte svarar förrän något har kommit in på modbus socketen. Det låser ju också den process som anropar. Alternativet är att man implementerar utan hängning så får anroparen polla istället. Vet inte om om det är en option i libmodbus att göra ett asynkront anrop men sådan optioner brukar man ju normalt ha.

Inte riktigt lika attraktivt att göra en wrapper för en slav alltså.
nifelheim
Den första
Inlägg: 2315
Blev medlem: 27 mars 2008, 22:31:16
Ort: stockholm

Re: Raspberry med 1wire och modbus

Inlägg av nifelheim »

Japp.
Efter att precis fått pymodbus servern att funka, hittade/insåg jag att libmodbus nog är vägen för mig.

Inga problem att läsa Norska (Python),
men ska man skriva felfritt är det betydligt enklare och går snabbare med Svenska (C/C++) :)
nifelheim
Den första
Inlägg: 2315
Blev medlem: 27 mars 2008, 22:31:16
Ort: stockholm

Re: Raspberry med 1wire och modbus

Inlägg av nifelheim »

inte glömt, men det var det där med tid......

Fick några timmar över ikväll, gjorde lite framsteg,
ska göra om det på en "ny fräsch" rpi3 när jag får lite mer tid och dokumentera owfs delen.
Denna hallonpaj har loggat temperatur länge och hade redan OWFS installerat. :)

Började med att installera libmodbus

Kod: Markera allt

sudo apt-get update
sudo apt-get install libmodbus5 libmodbus-dev
Laddade ner exempel koden random-test-server.c
https://github.com/stephane/libmodbus/b ... t-server.c


Lagt till tre avsnitt, markerat med //**************//


Kod: Markera allt

/*
 * Copyright © 2008-2014 Stéphane Raimbault <stephane.raimbault@gmail.com>
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include <stdio.h>
#ifndef _MSC_VER
#include <unistd.h>
#endif
#include <stdlib.h>
#include <errno.h>

#include <modbus.h>

int main(void)
{


//************************************************************************//

    FILE *fd;
    fd =fopen("/mnt/1wire/10.D98592010800/temperature","r");
    char text[20];
//************************************************************************//




    int s = -1;

    modbus_t *ctx;
    modbus_mapping_t *mb_mapping;

    ctx = modbus_new_tcp("127.0.0.1", 1502);
    /* modbus_set_debug(ctx, TRUE); */

    mb_mapping = modbus_mapping_new(500, 500, 500, 500);
    if (mb_mapping == NULL) {
        fprintf(stderr, "Failed to allocate the mapping: %s\n",
                modbus_strerror(errno));
        modbus_free(ctx);
        return -1;
    }
    s = modbus_tcp_listen(ctx, 1);
    modbus_tcp_accept(ctx, &s);


    for (;;) {
        uint8_t query[MODBUS_TCP_MAX_ADU_LENGTH];
        int rc;



//************************************************************************//
        fscanf(fd,"%[^\n]", text);
        mb_mapping->tab_input_registers[0] = (int)(strtof(text, NULL)*100);
//***********************************************************************//




        rc = modbus_receive(ctx, query);
        if (rc > 0) {
            /* rc is the query size */
            modbus_reply(ctx, query, rc, mb_mapping);
        } else if (rc == -1) {
            /* Connection closed by the client or error */
            break;
        }
    }

    printf("Quit the loop: %s\n", modbus_strerror(errno));

    if (s != -1) {
        close(s);
    }
    modbus_mapping_free(mb_mapping);
    modbus_close(ctx);
    modbus_free(ctx);

//************************************************************************//

   fclose(fd);
//************************************************************************//


    return 0; 
}
Först avsnittet öppnar temperaturfilen och deklarera en slaskvariabel att läsa från filen till.
Andra avsnittet läser filen som en sträng, omvandla till en float multlicera med 100 och omvandla till en integer,
det resultatet läggs till det första input registret (mb_mapping->tab_input_registers[0]).
Sista avsnittet stänger filen. :)

Döpte min ändrade fil till test-server.c

Kompilerade sedan koden med

Kod: Markera allt

gcc -I /usr/include/modbus test-server.c -o test-server -L/usr/lib/modbus -lmodbus
och körde med

Kod: Markera allt

./test-server


Kollade med modscan:
modscan.JPG

Valde controller enligt din instruktion, la till en tag, där jag skalade tillbaka den tidigare multiplikationen, inte hunnit kolla om det verkligen funkar
(eller om jag trunkat decimalerna)
tag.JPG
tryckte på play
temperatu.JPG
Det var framgång !
skalstrecken blir lite mongo, men då har jag något att träna på :)

Som server programmet är skrivet avslutas det när klienten kopplar ner,
så man får starta om det mellan varje test.

Det finns ingen felhantering alls i det jag la till och om det är lämpligt att multiplicera med 100 för att slippa flyttal,
beror ju helt på vad man har för värden.
Du har inte behörighet att öppna de filer som bifogats till detta inlägg.
Skriv svar