Sensore NPK con Arduino MKR1010

Buongiorno a tutti.
Sto cercando di leggere un sensore NPK di cui allego scheda

NPK all in one soil sensor manual(V1.3).pdf (395,0 KB)

attraverso un arduino MKR 1010 e scheda MAXRS485.
I collegamenti sono stati realizzati come da schema di seguito riportato.

senza lo schermo OLED, utilizzando i PIN di arduino 14 e 13 per TX e RX collegati rispettivamente a DI e RO della RS485. I pin DE e RE sono collegati rispettivamente al PIN 7 e PIN8 dell'arduino MKR.

Allego anche il codice


#include <Arduino.h>


////1.	indirizzo potassio TX:01 03 02 06 00 01 65 b3

const byte pota[] = {0x01, 0x03, 0x02, 0x06, 0x00, 0x01, 0x65, 0xb3};

////2.	indirizzo fosforo TX:01 03 02 05 00 01 95 b3
const byte phos[] = {0x01, 0x03, 0x02, 0x05, 0x00, 0x01, 0x95, 0xb3};

////3.	indirizzo azoto TX:01 03 02 04 00 01 c4 73
const byte nitro[] = {0x01, 0x03, 0x02, 0x04, 0x00, 0x01, 0xc4, 0x73};
#include <Arduino.h>

#define RE 8
#define DE 7


byte values[11];

void setup() {
  Serial.begin(9600);
  Serial1.begin(9600);
  pinMode(RE, OUTPUT);
  pinMode(DE, OUTPUT);

  delay(3000);
}

void loop() {
  byte val1, val2, val3;
  val1 = nitrogen();
  delay(250);
  val2 = phosphorous();
  delay(250);
  val3 = potassium();
  delay(250);

  Serial.print("Nitrogen: ");
  Serial.print(val1);
  Serial.println(" mg/kg");
  Serial.print("Phosphorous: ");
  Serial.print(val2);
  Serial.println(" mg/kg");
  Serial.print("Potassium: ");
  Serial.print(val3);
  Serial.println(" mg/kg");
  delay(2000);
}

byte nitrogen() {
  digitalWrite(DE, HIGH);
  digitalWrite(RE, HIGH);
  delay(10);
  if (Serial1.write(nitro, sizeof(nitro)) == 8) {
    digitalWrite(DE, LOW);
    digitalWrite(RE, LOW);
    for (byte i = 0; i < 7; i++) {
      values[i] = Serial1.read();
      Serial.print(values[i], HEX);
    }
    Serial.println();
  }
  return values[4];
}

byte phosphorous() {
  digitalWrite(DE, HIGH);
  digitalWrite(RE, HIGH);
  delay(10);
  if (Serial1.write(phos, sizeof(phos)) == 8) {
    digitalWrite(DE, LOW);
    digitalWrite(RE, LOW);
    for (byte i = 0; i < 7; i++) {
      values[i] = Serial1.read();
      Serial.print(values[i], HEX);
    }
    Serial.println();
  }
  return values[4];
}

byte potassium() {
  digitalWrite(DE, HIGH);
  digitalWrite(RE, HIGH);
  delay(10);
  if (Serial1.write(pota, sizeof(pota)) == 8) {
    digitalWrite(DE, LOW);
    digitalWrite(RE, LOW);
    for (byte i = 0; i < 7; i++) {
      values[i] = Serial1.read();
      Serial.print(values[i], HEX);
    }
    Serial.println();
  }
  return values[4];
}

il problema è che non riesco a leggere nulla. Ho sempre FFFFFFFFFF per tutte le letture.
Vi ringrazio in anticipo.

:warning:
Ti segnalo che, nella sezione in lingua Inglese, si può scrivere SOLO in Inglese ... quindi, per favore, la prossima volta presta più attenzione in quale sezione metti i tuoi post; questa volta esso è stato spostato, da un moderatore della sezione di lingua Inglese, nella sezione di lingua Italiana ... la prossima volta potrebbe venire direttamente eliminato. Grazie.

P.S.: Evitate di utilizzare la traduzione automatica fatta dal browser ... vi impedisce di capire la lingua della sezione dove andate a scrivere ...

Ho aggiornato il codice ma ancora nulla di fatto. Leggo sempre 0. Ho inserito la libreria ModbusMAster; vorrei aggiungere che la mia sonda trasmette i valori con 2 byte mentre il convertitore RS485 seriale è a 8 bit.

#include <ModbusMaster.h>

// Definisci l'oggetto ModbusMaster
ModbusMaster node;

// Indirizzi dei registri per azoto, fosforo e potassio
const uint16_t NITROGEN_REGISTER = 0x0204;
const uint16_t PHOSPHOROUS_REGISTER = 0x0205;
const uint16_t POTASSIUM_REGISTER = 0x0206;

// Pin per DE e RE
const int DE_PIN = A5;
const int RE_PIN = A6;

void setup() {
  Serial.begin(9600);
  Serial1.begin(9600); // Imposta la velocità di comunicazione per Serial1

  // Inizializza il nodo ModbusMaster
  node.begin(1, Serial1);  // Imposta l'ID del dispositivo Modbus (da 1 a 254 deve essere impostato sulla sonda o letto sul manuale) e la porta seriale
}

void loop() {
  // Leggi il valore di azoto dal registro di holding
  uint16_t nitrogenValue = readHoldingRegister(NITROGEN_REGISTER);
  Serial.print("Azoto: ");
  Serial.print(nitrogenValue);
  Serial.println(" mg/kg");

  // Leggi il valore di fosforo dal registro di holding
  uint16_t phosphorousValue = readHoldingRegister(PHOSPHOROUS_REGISTER);
  Serial.print("Fosforo: ");
  Serial.print(phosphorousValue);
  Serial.println(" mg/kg");

  // Leggi il valore di potassio dal registro di holding
  uint16_t potassiumValue = readHoldingRegister(POTASSIUM_REGISTER);
  Serial.print("Potassio: ");
  Serial.print(potassiumValue);
  Serial.println(" mg/kg");

  delay(2000);
}

// Funzione per leggere un registro di holding
uint16_t readHoldingRegister(uint16_t registerAddress) {
  // Imposta il pin DE su HIGH e il pin RE su HIGH
  digitalWrite(DE_PIN, HIGH);
  digitalWrite(RE_PIN, HIGH);
  delay(10);

  // Invia la richiesta Modbus per leggere i 16 bit del registro di holding
  uint8_t result = node.readHoldingRegisters(registerAddress, 1);

  // Imposta il pin DE su LOW e il pin RE su LOW
  digitalWrite(DE_PIN, LOW);
  digitalWrite(RE_PIN, LOW);

  if (result == node.ku8MBSuccess) {
    // Combina i due byte letti per ottenere il valore a 16 bit
    uint16_t value = node.getResponseBuffer(0);
    return value;  // Restituisce il valore letto
  } else {
    return 0;  // Restituisce 0 in caso di errore
  }
}

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.