I am trying to use zphs01b with esp8266MOD and till now I didn't figure out how to do it? For my project I can use raspberry Pi too if not esp8266MOD

Thread Starter

AnandSonali

Joined Oct 4, 2023
3
C-like:
#include <Wire.h>


// ZPHS01B sensor address

#define ZPHS01B_ADDR 0xFF



void setup() {

Serial.begin(9600);

Wire.begin();

}



void loop() {

// Request 5 bytes of data from the ZPHS01B sensor

Wire.beginTransmission(ZPHS01B_ADDR);

Wire.write(0x01);

Wire.write(0x86);

Wire.write(0x00);

Wire.write(0x00);

Wire.write(0x00);

Wire.write(0x00);

Wire.write(0x00);

Wire.write(0x79);

Wire.endTransmission();



// Wait for sensor to complete measurement

delay(100);



// Read data from sensor

Wire.requestFrom(ZPHS01B_ADDR, 9);

byte data[26];

for (int i = 0; i < 26; i++) {

   data = Wire.read();

}



// Convert raw sensor data to meaningful values

float temperature = ((data[11] * 256 + data[12]) - 435) / 100.0;

float humidity = data[13] * 256 + data[14];

float pm25 = (data[4] * 256 + data[5]) / 10.0;


// Print sensor data to serial monitor

Serial.print("Temperature: ");

Serial.print(temperature);

Serial.println(" C");

Serial.print("Humidity: ");

Serial.print(humidity);

Serial.println();

Serial.print("PM2.5: ");

Serial.print(pm25);

Serial.println(" ug/m3");



// Wait before taking next measurement

delay(5000);

}
 
Last edited by a moderator:

Thread Starter

AnandSonali

Joined Oct 4, 2023
3
Could please help me with the raspberry pi connection and code idea? Or If you know any source to get this as I'm new to this sensor world and don't have much knowledge to deal on my own.
 

geekoftheweek

Joined Oct 6, 2013
1,183
I haven't worked with the PI UART yet and after some searching I was not able to find a decent tutorial that actually made sense for what you will need to do. If you can wait for a few days I will do some experimenting this weekend and get back. It should be relatively easy to do, but I just don't have the details on hand at the moment to make it work.

Your code itself is relatively close to what you need to do... it's just using the wrong interface to communicate with your module.
 

geekoftheweek

Joined Oct 6, 2013
1,183
@AnandSonali I did some experimenting and came up with something. I have only worked with the serial port one other time so I didn't have the information I needed on hand or remembered much of what I did.

First off you need to enable the PI serial port. I have condensed https://www.abelectronics.co.uk/kb/article/1035/serial-port-setup-in-raspberry-pi-os into the following relevant instructions:

1) run sudo raspi-config
2) select Interface Options
3) select Serial Port
4) select No for the question of enabling login shell accessible over serial port
5) select Yes to enable serial port hardware
6) select Ok to finish.

It should ask if you would like to reboot at this time or if by chance you already have the serial port enabled it may skip the reboot.

In order to use the serial port your login has to be added to the dialout group:

sudo usermod -aG dialout <your login name>

I used a lot of https://blog.mbedded.ninja/programming/operating-systems/linux/linux-serial-ports-using-c-cpp/ for the basic program. It may not be necessary to set all the options as the default port settings are probably right due to the choices in raspi-config, but it's always good to set everything to make sure.

Hopefully this helps...

Code:
#include <stdio.h>
#include <string.h>

// Linux headers
#include <fcntl.h> // Contains file controls like O_RDWR
#include <errno.h> // Error integer and strerror() function
#include <termios.h> // Contains POSIX terminal control definitions
#include <unistd.h> // write(), read(), close()


int main(int argc, char* argsv[]) {
    int serial_port = open("/dev/ttyS0", O_RDWR);
    if (serial_port <0) {
        printf("Error %i from open: %s\n", errno, strerror(errno));
    }
    struct termios tty;

    if(tcgetattr(serial_port, &tty) != 0) {
        printf("Error %i from tcgetattr: %s\n", errno, strerror(errno));
    }
    tty.c_cflag &= ~PARENB; // Clear parity bit, disabling parity (most common)
    tty.c_cflag &= ~CSTOPB; // Clear stop field, only one stop bit used in communication (most common)
    tty.c_cflag |= CS8; // 8 bits per byte (most common)
    tty.c_cflag &= ~CRTSCTS; // Disable RTS/CTS hardware flow control (most common)
    tty.c_cflag |= CREAD | CLOCAL; // Turn on READ & ignore ctrl lines (CLOCAL = 1)
    tty.c_lflag &= ~ICANON;
    tty.c_lflag &= ~ECHO; // Disable echo
    tty.c_lflag &= ~ECHOE; // Disable erasure
    tty.c_lflag &= ~ECHONL; // Disable new-line echo
    tty.c_lflag &= ~ISIG; // Disable interpretation of INTR, QUIT and SUSP
    tty.c_iflag &= ~(IXON | IXOFF | IXANY); // Turn off s/w flow ctrl
    tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP|INLCR|IGNCR|ICRNL); // Disable any special handling of received bytes

    tty.c_oflag &= ~OPOST; // Prevent special interpretation of output bytes (e.g. newline chars)
    tty.c_oflag &= ~ONLCR; // Prevent conversion of newline to carriage return/line feed
    tty.c_cc[VTIME] = 10;    // Wait for up to 1s (10 deciseconds), returning as soon as any data is received.
    tty.c_cc[VMIN] = 0;
  
    if (tcsetattr(serial_port, TCSANOW, &tty) != 0) {
        printf("Error %i from tcsetattr: %s\n", errno, strerror(errno));
    }
  
    cfsetispeed(&tty, B9600);
    cfsetospeed(&tty, B9600);
  
    char serial_bytes[26];
  
    char keep_going =1;
    while(keep_going) {
        serial_bytes[0] = 0xff;
        serial_bytes[1] = 1;
        serial_bytes[2] = 0x86;
        serial_bytes[3] = 0;
        serial_bytes[4] = 0;
        serial_bytes[5] = 0;
        serial_bytes[6] = 0;
        serial_bytes[7] = 0;
        serial_bytes[8] = 0x79;
        int ret = write(serial_port, serial_bytes, 9);
        if (ret < 0) {
            printf("Error %i from write: %s\n", errno, strerror(errno));
            keep_going = 0;
        }
        else {
            usleep(100000); // same as delay(100) in your program
            ret = read(serial_port, serial_bytes, 26);
            if (ret < 0) {
                printf("Error reading: %s", strerror(errno));
                keep_going = 0;
            }
            else {
                float temperature = ((serial_bytes[11] * 256 + serial_bytes[12]) - 435) / 100.0;

                float humidity = serial_bytes[13] * 256 + serial_bytes[14];

                float pm25 = (serial_bytes[4] * 256 + serial_bytes[5]) / 10.0;

                // Print sensor data to serial monitor
                printf"Temperature: %.01f C\n", temperature);
                printf"Humidity: %.01f \%\n", humidity);
                printf"PM2.5: %.01f ug/m3\n", pm25);

                sleep(5);
            }
        }
    }
}
Edit:
I have had problems with float variables in the past for some reason (maybe it's just me)
You may have to do something like:
Code:
float f1 = (float)serial_bytes[11];
float f2 = (float)256;
float f3 = (float)serial_bytes[12];
float f4 = (float)435;
float f5 = 100;

float temperature = (f1 * f2 + f3 - f4) / f5;
 
Last edited:
Top