Jump to content

SUBIECTE NOI
« 1 / 5 »
RSS
Amenintat cu moartea de un numar ...

La multi ani @AndReW99!

Alegere masina £15000 uk

TVR vrea sa lanseze o platforma d...
 Strategie investie pe termen lung...

Modulator FM ptr auto alimentat p...

orange cablu f.o. - internet fara...

Robinet care comuta traseul
 A fost lansata Fedora 40

Samsung S24 plus

Imi iau un Dell? (Vostro vs others)

Abonati Qobuz?
 transport -tren

Platforma electronica de eviden&#...

Cot cu talpa montat stramb in per...

Sfat achizitie sistem audio pentr...
 

Senzor sol cu RS485 si arduino uno

* * * * * 1 votes
  • Please log in to reply
21 replies to this topic

#1
vladuzz7

vladuzz7

    Active Member

  • Grup: Members
  • Posts: 1,067
  • Înscris: 17.05.2012
Salut!
Am cumparat din china un senzor pentru sol care poate citi temperatura, umiditate, PH, NPK( azot, fosfor, potasiu).
Problema e ca am crezut ca e destul de simplu de facut codul si nu imi dau seama cum sa folosesc adresele.
O sa las atasat un fel de datasheet dat de vanzator. Spre sfarsit dau ei un frame de 8 bytes care zic ca pt  frameul ala se pot citi umiditate, temperatura si conductivitate( asta fiind pt alt senzor din aceeasi familie..cred ca e un fel de datasheet general)
Eu am facut partea hardware, am pus intre senzor si arduino un modul cu Max485, am incercat si un cod doar pt PH, citeam o valoare de 655 si dupa am citit si 2.5. Am incercat sa pun frame-ul ala dat de ei si degeaba. Bine nu prea are niciun sens ce am facut eu acolo cu frame-ul si dupa sa citesc PH-ul.
Ca sa concluzionez nu stiu cum sa aleg adresele( sau inquiry frame-ul ala pt senzorul meu) si dupa sa incep sa citesc pe fiecare in parte..
M-am inspirat si de aici https://forum.arduin...k-sensor/853077

Codul e de pe net si am incercat sa il adaptez:
#include <Wire.h>
#include <SoftwareSerial.h> //Library to convert Digital Output pins of the board to transmitter as well as receiver

#define RE 8
#define DE 7

const byte ph[]	 = {0x01,0x03,0x00,0x00,0x00,0x03,0x05,0xCB};
byte values[11];
SoftwareSerial mod(2,3); // RX, TX ( Creates a new SoftwareSerial object )

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

void loop() {
float val1;
val1 = Ph();
delay(250);

Serial.print("PH : ");
Serial.println(val1);
delay(2000);
}
float Ph(){
float PH3and4;
digitalWrite(DE,HIGH);
digitalWrite(RE,HIGH);
delay(10);
if(mod.write(ph,sizeof(ph))==8){
digitalWrite(DE,LOW);
digitalWrite(RE,LOW);
// When we send the inquiry frame to the NPK sensor, then it replies with the response frame
// now we will read the response frame, and store the values in the values[] arrary, we will be using a for loop.
for(byte i=0;i<7;i++){
//Serial.print(mod.read(),HEX);
values[i] = mod.read();
//Serial.println(values[i],HEX);
}
PH3and4 = (((values[3] * 256.0) + values[4])/100); // converting hexadecimal to decimal
Serial.println();
}
return (PH3and4);
}

Attached Files


Edited by vladuzz7, 16 January 2022 - 17:38.


#2
mihaicozac

mihaicozac

    Guru Member

  • Grup: Senior Members
  • Posts: 15,595
  • Înscris: 05.12.2005
Aria "values" memorează datele din senzor, iar în funcție de lungimea acelor date citești un byte sau 2 bytes dacă ai integer sau float sau 4 bytes pt. long, deși variabile long nu prea cred să fie.
Dacă ai un byte citirea este simplă;  
  
byte mySensorByte = value[x];

unde x este poziția în arie, care începe cu zero, deci atenție la adresă, că am văzut că în cod ai bucla "for" doar până la 7 deși aria e declarată de 11 bytes.
Dacă ai variabile pe mai mulți bytes sunt 2 variante, fie cu pointer fie cu concatenare:
  
int mySensorInt = value[x] << 8 + value[x + 1];
//sau
int mySensorInt = value[x] * 256 + value[x + 1];

sau
  
int mySensorInt = value[x] << 8 + value[x-1];

funcție de pozița relativă a celor 2 bytes, MSB și LSB, în arie (endianess).

aceeași tehnică de folosește și la float pe 2 bytes, iar dacă ai un long pe 4 bytes se folosește deplasarea datelor citite din arie în variabila long:
long mySensorLong = value[x] << 24 + value[x + 1] << 16 + value[x + 2] << 8 + value[x + 3];

sau x - 1, etc.  dacă sunt aranjați invers.
sau folosești o minibuclă "for" cu 4 pași;
long mySensorLong = 0;
for(byte x = 0; x < 4; x++) mySensorLong = value[x] << (8 * (3 - x));

Citirea datelor din arie trebuie făcută după ce ai citit datele din senzor, deci codul se plasează mai jos decât SerialRead()... altfel o să ai o întârziere de un ciclu program în interpretatrea datelor.

Edited by mihaicozac, 16 January 2022 - 18:59.


#3
mihaicozac

mihaicozac

    Guru Member

  • Grup: Senior Members
  • Posts: 15,595
  • Înscris: 05.12.2005
LE; float e tot pe 4 bytes ca şi long, deci se foloseşte aceeaşi metodă.

#4
vladuzz7

vladuzz7

    Active Member

  • Grup: Members
  • Posts: 1,067
  • Înscris: 17.05.2012

View Postmihaicozac, on 16 ianuarie 2022 - 18:56, said:

Aria "values" memorează datele din senzor, iar în funcţie de lungimea acelor date citeşti un byte sau 2 bytes dacă ai integer sau float sau 4 bytes pt. long, deşi variabile long nu prea cred să fie.
Dacă ai un byte citirea este simplă;  
  
byte mySensorByte = value[x];

unde x este poziţia în arie, care începe cu zero, deci atenţie la adresă, că am văzut că în cod ai bucla "for" doar până la 7 deşi aria e declarată de 11 bytes.
Dacă ai variabile pe mai mulţi bytes sunt 2 variante, fie cu pointer fie cu concatenare:
  
int mySensorInt = value[x] << 8 + value[x + 1];
//sau
int mySensorInt = value[x] * 256 + value[x + 1];

sau
  
int mySensorInt = value[x] << 8 + value[x-1];

funcţie de poziţa relativă a celor 2 bytes, MSB şi LSB, în arie (endianess).

aceeaşi tehnică de foloseşte şi la float pe 2 bytes, iar dacă ai un long pe 4 bytes se foloseşte deplasarea datelor citite din arie în variabila long:
long mySensorLong = value[x] << 24 + value[x + 1] << 16 + value[x + 2] << 8 + value[x + 3];

sau x - 1, etc.  dacă sunt aranjaţi invers.
sau foloseşti o minibuclă "for" cu 4 paşi;
long mySensorLong = 0;
for(byte x = 0; x < 4; x++) mySensorLong = value[x] << (8 * (3 - x));

Citirea datelor din arie trebuie făcută după ce ai citit datele din senzor, deci codul se plasează mai jos decât SerialRead()... altfel o să ai o întârziere de un ciclu program în interpretatrea datelor.
multumesc frumos
Credeti ca frame ul ala citeste toti parametri pe care ii are senzorul ? sau trebuie fiecare cu frame-ul lui ?
Ca al meu are pe langa PH si temperatura, umiditate si NPK. Nu imi dau seama daca e corect..nu imi dau seama cum le diferentiez daca eu citesc totti cei 6 parametri, fiecare avand 2 bytes, asta ar insemna ca e un frame cu 17 bytes( cred?)  conform cu ce zic ei acolo in datasheet. asta nu imi e clar

#5
mihaicozac

mihaicozac

    Guru Member

  • Grup: Senior Members
  • Posts: 15,595
  • Înscris: 05.12.2005
Datasheet-ul ar trebui să explice cum se face citirea. Senzorii au de obicei regiştri interni (practic adrese de memorie) care se pot accesa individual, dacă ai bibliotecă gata scrisă foloseşti funcţiile de acolo pt. ce parametri te interesează, dacă nu există aşa ceva trebuie să scrii personal funcţiile de citire, ceea ce nu e foarte greu, trimiţi adresa device-ului plus comanda de citire apoi trimiţi adresa registrului de interes după care iniţiezi secvenţa de citire a registrului, şi dacă e cazul faci conversia din valoarea raw în una uşor de înţeles, de ex. temperatura poate fi pe 16 bit şi 0x0000 să însemne -50C iar 0xFFFF +125C, între astea 2 extreme ai 65536 de valori pt. ecartul de 175C, asta desigur dacă nu îţi dă direct un float cu temperatura gata convertitiă, dar nu este uzual.
Uite un exemplu scris de mine pt. citirea unei tensiuni de la un convertor analog-digital, pt. un tester de baterii:
int adc_get_mV(byte adc) {						 //CITIRE DIN ADS1115
byte high_byte, low_byte;
i2c_start_wait(adc + I2C_WRITE);
i2c_write(0x01); //CONFIG REGISTER
i2c_write(0x02); //MSB REG
i2c_write(0x03); //LSB REG
i2c_stop();
i2c_start_wait(adc + I2C_WRITE);
i2c_write(0x00); //DATA REGISTER
i2c_rep_start(adc + I2C_READ);
high_byte = i2c_readAck();
low_byte = i2c_readAck();
i2c_stop();
unsigned int mV = high_byte * 256 + low_byte; //CONVERSIE CITIRI ADS IN MILIVOLTI
return mV;
}

Iar în loop folosesc funcţia asta de câte ori am nevoie:
int batt_voltage1 = adc_get_mv(0x48 << 1);


Edited by mihaicozac, 16 January 2022 - 22:16.


#6
vladuzz7

vladuzz7

    Active Member

  • Grup: Members
  • Posts: 1,067
  • Înscris: 17.05.2012
Sincer sa fiu, ma depaseste un pic partea de programare, inteleg in mare, dar nu stiu daca reusesc sa aplic in cazul de fata.
Chinezul nu prea e clar in datasheet. Ce mi-a dat el au fost mai multe datasheeturi si l-am ales eu pe asta pe care l-am atasat si la postare. Ideea e ca el zice ca vrea sa citeasca umiditate, temperatura si conductivitate impreuna. Eu nu am conductivitate si am PH, iar in plus am si N, P, K. Neavand conductivitate, adresa lui ( 0x02 cum e acolo) pare ca nu mai e in continuare si nu inteleg cum as face citirea nefiind consecutiv.. E tot o varza :))
Eu ma gandeam ca merge sa bag frame ul ala, sa imi dea nu stiu cati bytes si sa ii citesc pe rand, dar nu prea merge cred ca nu stiu care cum e..macar de reuseam sa citesc frame ul de iesire sau ceva de genul si imi dadeam eu seama care cum e cred..

Attached Files



#7
luka

luka

    Junior Member

  • Grup: Members
  • Posts: 68
  • Înscris: 25.11.2003
MODBUS merge pe principiul intrebare , raspuns.
Daca ne luam dupa datasheet ai un unicast inquiry de 3 parametri,

const byte ph[]  = {0x01, 0x03, 0x00, 0x00, 0x00, 0x03, 0x05, 0xCB};
De la slave ............ 0x1
Citeste  ..........................0x03
Parametri .....................................................  0x00003
incepand de la adr ....................0x0000

Raspunsul contine cate 2 bytes pentru fiecare parametru deci 6, si in total 11 bytes.
Codul tau C citeste doar 7 bytes, deci nu este corect ar trebui sa citesti 11.

Pe acceasi idee poti incerca citiri individuale de un singur parametru de exemplu
pentru Humidity (adresa 0x0000):

const byte hum[]  = {0x01, 0x03, 0x00, 0x00, 0x00, 0x01, 0x84, 0x0A};
Raspunsul ar fi de genul:
0x01, 0x03, 0x02, hum_high, hum_low, crc_low, crc_high

sau pentru PH (adresa 0x0003)
const byte ph[]   = {0x01, 0x03, 0x00, 0x03, 0x00, 0x01, 0x74, 0x0A};

Pentru citiri individuale raspunsul are 7 bytes deci poti folosi codul original.
La fiecare inquiry trebuie sa calculezi CRC, sper ca stii cum.

#8
gmartau

gmartau

    Member

  • Grup: Members
  • Posts: 639
  • Înscris: 30.04.2008
Ca sa citesti umiditatea, temperatura, conductivitatea, PH-ul, Azotul, Fosforul, Potasiul, adica 7 valori consecutive trimiti pe serial tabloul de mai jos:
{0x01, 0x03, 0x00, 0x00, 0x00, 0x07, 0x04, 0x08}
Acel 0x07 inseamna ca ceri 7 pozitii (valori), ultimele doua valori 0x04, 0x08 reprezinta crc16/mod calculat din sirul anterior.

Citesti raspunsul intr-un tablou de 3 + 7*2 + 2 = 19 octeti
Pe pozitia 0 trebuie sa fie 0x00, pe pozitia 1 trebuie sa fie 0x03, pe pozitia 2 numarul de octeti, in acest caz 2*7 valori=14 octeti.
Valorile ce te intereseaza incep de pe pozitia 3 si sunt cate doi octeti pentru fiecare valoare in ordinea de mai sus. Asamblezi octetii pentru a obtine valoarea, pentru unele trebuie sa imparti la 10.

#9
vladuzz7

vladuzz7

    Active Member

  • Grup: Members
  • Posts: 1,067
  • Înscris: 17.05.2012

View Postluka, on 16 ianuarie 2022 - 22:49, said:

MODBUS merge pe principiul intrebare , raspuns.
Daca ne luam dupa datasheet ai un unicast inquiry de 3 parametri,

const byte ph[]  = {0x01, 0x03, 0x00, 0x00, 0x00, 0x03, 0x05, 0xCB};
De la slave ............ 0x1
Citeste  ..........................0x03
Parametri .....................................................  0x00003
incepand de la adr ....................0x0000

Raspunsul contine cate 2 bytes pentru fiecare parametru deci 6, si in total 11 bytes.
Codul tau C citeste doar 7 bytes, deci nu este corect ar trebui sa citesti 11.

Pe acceasi idee poti incerca citiri individuale de un singur parametru de exemplu
pentru Humidity (adresa 0x0000):

const byte hum[]  = {0x01, 0x03, 0x00, 0x00, 0x00, 0x01, 0x84, 0x0A};
Raspunsul ar fi de genul:
0x01, 0x03, 0x02, hum_high, hum_low, crc_low, crc_high

sau pentru PH (adresa 0x0003)
const byte ph[]   = {0x01, 0x03, 0x00, 0x03, 0x00, 0x01, 0x74, 0x0A};

Pentru citiri individuale raspunsul are 7 bytes deci poti folosi codul original.
La fiecare inquiry trebuie sa calculezi CRC, sper ca stii cum.
cred ca asta e fix ce caut
e prima data cand lucrez cu asta si habar nu am CRC-ul acela.
Si mi-ar fi mult mai usor de inteles sa le iau individual decat toate deodata.
As fi foarte recunoscator daca mi-ai explica cum sta treaba cu CRC-ul, dau o bere :D

#10
gmartau

gmartau

    Member

  • Grup: Members
  • Posts: 639
  • Înscris: 30.04.2008
https://crccalc.com/
Alegi Hex, Bagi carnatul de 6 octeti in calculatorul online, fara 0x sau alte separatoare, apesi pe CRC-16 si te uiti pe coloana Result la CRC-16/MODBUS. In program, valorile trebuie introduse invers, incepi cu octetul mai putin semnificativ.

Edited by gmartau, 16 January 2022 - 23:26.


#11
vladuzz7

vladuzz7

    Active Member

  • Grup: Members
  • Posts: 1,067
  • Înscris: 17.05.2012
va multumesc din suflet amandurora
Am avut treaba la munca si nu am mai avut timp sa ma ocup de el
Am calculat restul de frame si le-am pus intr-un tabel, azi si maine incerc sa citesc fiecare parametru separat, sa vad daca iese ceva
Era fain sa pot sa le citesc pe toate odata sa nu pun acelasi cod de 6 ori, dar in lipsa de cunostinte merge si asa Posted Image)
PS:
Am revenit cu citirea temperaturii..imi citeste prima data ceva cu 2.5 si apoi numai in valoarea aia de 655.35 merge.. nu inteleg ce are
Pare ca e valoarea maxima de FFFF, orice adresa as pune citeste valoarea asta, am alimentata si separat cu 12V si ground comun...nimic tot asa, chiar si deconectat de tot
Cod:
#include <Wire.h>
#include <SoftwareSerial.h> //Library to convert Digital Output pins of the board to transmitter as well as receiver

#define RE 8
#define DE 7

const byte tempe[]	 = {0x01,0x03,0x00,0x01,0x00,0x01,0xD5,0xCA};
byte values[11];
SoftwareSerial mod(2,3); // RX, TX ( Creates a new SoftwareSerial object )

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

void loop() {
float val1;
val1 = temp();
delay(250);

Serial.print("Temperature : ");
Serial.println(val1);
delay(2000);
}
float temp(){
float tp;
digitalWrite(DE,HIGH);
digitalWrite(RE,HIGH);
delay(10);
if(mod.write(tempe,sizeof(tempe))==8){
digitalWrite(DE,LOW);
digitalWrite(RE,LOW);
// When we send the inquiry frame to the NPK sensor, then it replies with the response frame
// now we will read the response frame, and store the values in the values[] arrary, we will be using a for loop.
for(byte i=0;i<7;i++){
//Serial.print(mod.read(),HEX);
values[i] = mod.read();
//Serial.println(values[i],HEX);
}
tp = (((values[3] * 256.0) + values[4])/100); // converting hexadecimal to decimal
Serial.println();
}
return (tp);
}


schema am folosit-o pe asta..doar ca al meu se alimenteaza intre 4.5 si 30 V si l-am conectat la arduinol a 5V si fara OLED

Attached Files


Edited by vladuzz7, 29 January 2022 - 00:17.


#12
vladuzz7

vladuzz7

    Active Member

  • Grup: Members
  • Posts: 1,067
  • Înscris: 17.05.2012
pur si simplu nu vrea..wiringul e corect, practic nu primeste niciun raspuns de la senzor

Attached Files


Edited by vladuzz7, 29 January 2022 - 01:05.


#13
luka

luka

    Junior Member

  • Grup: Members
  • Posts: 68
  • Înscris: 25.11.2003
Incearca cu viteza de 4800 baud, vad ca in spec zice ca asta este defualt. Cine stie poate nu merge la 9600.
Daca nici asa nu raspunde trebuie sa te uiti pe linie cu osciloscop sa vezi daca se genereaza inquiry.
Poate nu trimite arduino nimic.

#14
vladuzz7

vladuzz7

    Active Member

  • Grup: Members
  • Posts: 1,067
  • Înscris: 17.05.2012

View Postluka, on 29 ianuarie 2022 - 15:40, said:

Incearca cu viteza de 4800 baud, vad ca in spec zice ca asta este defualt. Cine stie poate nu merge la 9600.
Daca nici asa nu raspunde trebuie sa te uiti pe linie cu osciloscop sa vezi daca se genereaza inquiry.
Poate nu trimite arduino nimic.
nici cu 4800 nu merge, imi da doar niste artefacte pe output..niste caractere chinezesti si alte cele.
Osciloscop nu am decat unul foarte vechi si nu cred ca pot sa vad semnalele cu el :(
am vazut ca au mai avut unii probleme din astea si tot asa cu 4800 au reusit, altii au facut CRC-ul in cod sa se calculeze automat si altii nu au reusit niciodata. Dar sunt foarte putine informatii.
Bine ar fi sa reusesc sa citesc orice de pe el, dar nu e nimic.

#15
mihaicozac

mihaicozac

    Guru Member

  • Grup: Senior Members
  • Posts: 15,595
  • Înscris: 05.12.2005
Dacă ai răspuns din senzor îmseamnă că eşti pe drumul cel bun.
E normal să ai "chinezării" pe monitor, nu pt. că e chinezesc senzorul, ci pt. că transmite octeţi "raw", adică neformataţi, aşa cum cere monitorul serial din Arduino.
Pasul următor ar fi să memorezi octeţii primiţi într-o arie apoi să îi tipăreşti separat pe monitor ca valori hex sau decimal, cum îţi este mai uşor de interpretat, apoi se poate vedea cam ce e acolo.

#16
vladuzz7

vladuzz7

    Active Member

  • Grup: Members
  • Posts: 1,067
  • Înscris: 17.05.2012
PS: Se pare ca ati avut dreptate. am pus la mod.begin 4800 si pare ca citeste ceva, daaar nu citeste ce trebuie..
Nitrogen: 1 3 2 0 0 B8 44  = 0 mg/kg
Phosphorous: 1 3 2 0 0 B8 44  = 0 mg/kg
  Potassium: 1 3 2 0 0 B8 44  = 0 mg/kg
  PH: 1 3 2 0 5A 38 7F  = 90
  Moisture: FF FF FF FF FF FF FF  = 255 %
Imi cer scuze ca probabil sunt informatiile un pic amestecate, dar am incercat prea multe si nici eu nu mai stiu exact ce merge si ce nu Posted Image))

View Postmihaicozac, on 29 ianuarie 2022 - 17:14, said:

Dacă ai răspuns din senzor îmseamnă că eşti pe drumul cel bun.
E normal să ai "chinezării" pe monitor, nu pt. că e chinezesc senzorul, ci pt. că transmite octeţi "raw", adică neformataţi, aşa cum cere monitorul serial din Arduino.
Pasul următor ar fi să memorezi octeţii primiţi într-o arie apoi să îi tipăreşti separat pe monitor ca valori hex sau decimal, cum îţi este mai uşor de interpretat, apoi se poate vedea cam ce e acolo.
asa imi pare si mie ca vrea sa citeasca ceva, dar chinezaria tot chinezarie e..chiar daca e 90 euro

PPS: Am pus senzorul intr-un ghiveci si se pare ca citeste ceva, sa zic ca NPK-ul pare corect, dar PH-ul nu e corect si nici Moisture ( care de fapt e temperatura). Credeam ca e din cauza ca aveam un octet gresit, dar l-am modificat si tot asa face cu FF. O sa incerc sa modific codul din nou..poate reusesc. Cred totusi ca de fapt 71 la PH inseamna 7.1, care e mult mai credibil pt ca pt PH masoara intre 3 si 9

Attached Files


Edited by vladuzz7, 29 January 2022 - 17:37.


#17
mihaicozac

mihaicozac

    Guru Member

  • Grup: Senior Members
  • Posts: 15,595
  • Înscris: 05.12.2005
Îţi tipăreşte valorile predefinite în arii, nu ce citeşte de pe serial.
În  loop() nu văd nicăieri ceva cod care să citească datele primite de la senzor, gen Serial.read().

#18
vladuzz7

vladuzz7

    Active Member

  • Grup: Members
  • Posts: 1,067
  • Înscris: 17.05.2012

View Postmihaicozac, on 29 ianuarie 2022 - 17:37, said:

Îţi tipăreşte valorile predefinite în arii, nu ce citeşte de pe serial.
În  loop() nu văd nicăieri ceva cod care să citească datele primite de la senzor, gen Serial.read().
Am folosit urmatorul cod :
#include <AltSoftSerial.h>
// RO to pin 8 & DI to pin 9 when using AltSoftSerial
#define RE 6
#define DE 7
const byte nitro[] =		 {0x01, 0x03, 0x00, 0x04, 0x00, 0x01, 0xC5, 0xCB};
const byte phos[] =		 {0x01, 0x03, 0x00, 0x05, 0x00, 0x01, 0x94, 0x0B};
const byte pota[] =		 {0x01, 0x03, 0x00, 0x06, 0x00, 0x01, 0x64, 0x0B};
const byte soil_ph[] =	 {0x01, 0x03, 0x00, 0x03, 0x00, 0x01, 0x74, 0x0A};
const byte soil_moist[] =	 {0x01, 0x03, 0x00, 0x00, 0x00, 0x01, 0x84, 0x0A};
const byte soil_temp[] =	 {0x01, 0x03, 0x00, 0x01, 0x00, 0x01, 0xD5, 0xCA};
byte values[11];
AltSoftSerial mod;
void setup() {
Serial.begin(9600);
mod.begin(4800);
pinMode(RE, OUTPUT);
pinMode(DE, OUTPUT);
// put RS-485 into receive mode
digitalWrite(DE, LOW);
digitalWrite(RE, LOW);
delay( 1000 );
}
void loop() {
byte val1, val2, val3, val4, val5, val6;
Serial.print(" Nitrogen: ");
val1 = nitrogen();
Serial.print(" = ");
Serial.print(val1);
Serial.println(" mg/kg");
delay(250);
Serial.print("Phosphorous: ");
val2 = phosphorous();
Serial.print(" = ");
Serial.print(val2);
Serial.println(" mg/kg");
delay(250);
Serial.print(" Potassium: ");
val3 = potassium();
Serial.print(" = ");
Serial.print(val3);
Serial.println(" mg/kg");
Serial.print(" PH: ");
val4 = ph();
Serial.print(" = ");
Serial.print(val4);
Serial.println();
Serial.print(" Moisture: ");
val5 = moisture();
Serial.print(" = ");
Serial.print(val5);
Serial.println(" %");

Serial.println();

Serial.print(" Temperature: ");
val5 = temperature();
Serial.print(" = ");
Serial.print(val6);
Serial.println(" Celsius");

Serial.println();
delay(1000);
}
byte temperature() {
// clear the receive buffer
mod.flushInput();
// switch RS-485 to transmit mode
digitalWrite(DE, HIGH);
digitalWrite(RE, HIGH);
delay(10);
// write out the message
for (uint8_t i = 0; i < sizeof(soil_temp); i++ ) mod.write( soil_temp[i] );
// wait for the transmission to complete
mod.flush();

// switch RS-485 to receive mode
digitalWrite(DE, LOW);
digitalWrite(RE, LOW);
// crude delay to allow response bytes to be received!
delay(100);
// read in the received bytes
for (byte i = 0; i < 7; i++) {
values[i] = mod.read();
Serial.print(values[i], HEX);
Serial.print(' ');
}
return values[4];
}
byte moisture() {
// clear the receive buffer
mod.flushInput();
// switch RS-485 to transmit mode
digitalWrite(DE, HIGH);
digitalWrite(RE, HIGH);
delay(10);
// write out the message
for (uint8_t i = 0; i < sizeof(soil_moist); i++ ) mod.write( soil_moist[i] );
// wait for the transmission to complete
mod.flush();

// switch RS-485 to receive mode
digitalWrite(DE, LOW);
digitalWrite(RE, LOW);
// crude delay to allow response bytes to be received!
delay(100);
// read in the received bytes
for (byte i = 0; i < 7; i++) {
values[i] = mod.read();
Serial.print(values[i], HEX);
Serial.print(' ');
}
return values[4];
}
byte ph() {
// clear the receive buffer
mod.flushInput();
// switch RS-485 to transmit mode
digitalWrite(DE, HIGH);
digitalWrite(RE, HIGH);
delay(10);
// write out the message
for (uint8_t i = 0; i < sizeof(soil_ph); i++ ) mod.write( soil_ph[i] );
// wait for the transmission to complete
mod.flush();

// switch RS-485 to receive mode
digitalWrite(DE, LOW);
digitalWrite(RE, LOW);
// crude delay to allow response bytes to be received!
delay(100);
// read in the received bytes
for (byte i = 0; i < 7; i++) {
values[i] = mod.read();
Serial.print(values[i], HEX);
Serial.print(' ');
}
return values[4]/10;
}
byte nitrogen() {
// clear the receive buffer
mod.flushInput();
// switch RS-485 to transmit mode
digitalWrite(DE, HIGH);
digitalWrite(RE, HIGH);
delay(10);
// write out the message
for (uint8_t i = 0; i < sizeof(nitro); i++ ) mod.write( nitro[i] );
// wait for the transmission to complete
mod.flush();

// switch RS-485 to receive mode
digitalWrite(DE, LOW);
digitalWrite(RE, LOW);
// crude delay to allow response bytes to be received!
delay(100);
// read in the received bytes
for (byte i = 0; i < 7; i++) {
values[i] = mod.read();
Serial.print(values[i], HEX);
Serial.print(' ');
}
return values[4];
}
byte phosphorous() {
mod.flushInput();
digitalWrite(DE, HIGH);
digitalWrite(RE, HIGH);
delay(10);
for (uint8_t i = 0; i < sizeof(phos); i++ ) mod.write( phos[i] );
mod.flush();
digitalWrite(DE, LOW);
digitalWrite(RE, LOW);
delay(100);
for (byte i = 0; i < 7; i++) {
values[i] = mod.read();
Serial.print(values[i], HEX);
Serial.print(' ');
}
return values[4];
}
byte potassium() {
mod.flushInput();
digitalWrite(DE, HIGH);
digitalWrite(RE, HIGH);
delay(10);
for (uint8_t i = 0; i < sizeof(pota); i++ ) mod.write( pota[i] );
mod.flush();
digitalWrite(DE, LOW);
digitalWrite(RE, LOW);
delay(100);
for (byte i = 0; i < 7; i++) {
values[i] = mod.read();
Serial.print(values[i], HEX);
Serial.print(' ');
}
return values[4];
}


Ce obtin acum e:
Nitrogen: 1 3 2 0 12 38 49  = 18 mg/kg
Phosphorous: 1 3 2 0 18 B8 4E  = 24 mg/kg
  Potassium: 1 3 2 0 3D 79 95  = 61 mg/kg
  PH: 1 3 2 0 45 79 B7  = 6
  Moisture: 1 3 2 1 48 B9 E2  = 72 %
  Temperature: 1 3 2 0 9C B8 2D  = 0 Celsius
Singura chestie care nu imi place e temperatura, nu stiu de ce da asa, iar la PH am impartit eu la 10 sa imi dea doar partea intreaga, momentan ca trebuie sa aflu cum fac sa fie cu virgula
Update 1: Am gasit ce era cu temperatura..lasasem ce era la moisture, e gresit in codul de mai sus, lasesem  val5
Update 2: Obtin urmatoarele:
Nitrogen: 1 3 2 0 12 38 49  = 18 mg/kg
Phosphorous: 1 3 2 0 19 79 8E  = 25 mg/kg
  Potassium: 1 3 2 0 3E 39 94  = 62 mg/kg
  PH: 1 3 2 0 44 B8 77  = 6
  Moisture: 1 3 2 1 4D 79 E1  = 77 %
  Temperature: 1 3 2 0 9E 39 EC  = 158 Celsius
Acuma problema e cum fac eu sa fie cu virgula, ca sunt 15.8 grade si 6, ceva la PH..

Edited by vladuzz7, 29 January 2022 - 18:04.


Anunturi

Second Opinion Second Opinion

Folosind serviciul second opinion ne puteți trimite RMN-uri, CT -uri, angiografii, fișiere .pdf, documente medicale.

Astfel vă vom putea da o opinie neurochirurgicală, fără ca aceasta să poată înlocui un consult de specialitate. Răspunsurile vor fi date prin e-mail în cel mai scurt timp posibil (de obicei în mai putin de 24 de ore, dar nu mai mult de 48 de ore). Second opinion – Neurohope este un serviciu gratuit.

www.neurohope.ro

0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users

Forumul Softpedia foloseste "cookies" pentru a imbunatati experienta utilizatorilor Accept
Pentru detalii si optiuni legate de cookies si datele personale, consultati Politica de utilizare cookies si Politica de confidentialitate