Read Uart based sensor data on nrf5340 using VsCode?

Hi,

I'am using the  Ultrasonic Oxygen Senor with the nrf5340, the output is like this "photo" I want to calculate the concentration and the purity and with this values I had wrong results, so can you help to solve this problem?

 I am using this code

4857.gasboard.zip

 and here is my result.


this technical specification for my sensor.

 https://en.gassensor.com.cn/Product_files/Specifications/Gasboard%207500H%20series%20technical%20specification.pdf?fbclid=IwAR0R1P0FlwkPzhew7jBYVzL-rvtESB1ob2HGF0OE4bngaI5jP8ktZfFMoMo 

Could you please help me to solve this problem

Parents Reply
  • If what you are currently trying to do is simply to read data from your sensor with some basic UART sample, then I would recommend you read through the communication protocol part of the specification. It tells you in detail how you are supposed to communicate with the sensor.

    It looks like you have to send a specific command to the sensor to get data in return, are you doing this?

    -Einar

Children
  • Hi,
    No, I am not sending anything to the sensor, please help me how to send a specific command and what is this command?

  • Looks like you're using Zephyr's uart_irq API in your code, which uses uart_irq_tx_ready() and uart_fifo_fill() to send data.

    Read about it here:

    http://developer.nordicsemi.com/nRF_Connect_SDK/doc/latest/zephyr/hardware/peripherals/uart.html#uart-interrupt-api

    The communication protocol is explained in the data sheet you linked in your original question. Please read it.

  • Thank you I understand and I write an example code, but no result.

    #include <zephyr.h>
    #include <device.h>
    #include <devicetree.h>
    #include <drivers/uart.h>
    #include <sys/printk.h>
    uint8_t uart_buf[1024];
    uint8_t buf[] = {17, 1, 1, 237};//11 01 01 ED
    int count;
    void uart_cb(const struct device *x, void *user_data)
    {
    	uart_irq_update(x);
    	int data_length = 0;
    	if (uart_irq_tx_ready(x)) {
    	(void)uart_fifo_fill(x, buf, sizeof(buf));
    	uart_irq_tx_disable(x);
    	}
    	if (uart_irq_rx_ready(x)) {
    		data_length = uart_fifo_read(x, uart_buf, sizeof(uart_buf));
    		uart_buf[data_length] = 0;
    	}
        uart_fifo_fill(x, uart_buf, data_length);
    }
    
    void main(void)
    {
    
        printk("sensor program start!\n"); //output on UART0, which is default for logging
    		
    
    
    const struct device *uart = device_get_binding("UART_1");
    
        struct uart_config cfg ;
        cfg.baudrate = 9600 ;
        cfg.parity = UART_CFG_PARITY_NONE ;
        cfg.stop_bits = UART_CFG_STOP_BITS_1 ;
        cfg.data_bits = UART_CFG_DATA_BITS_8 ;
        cfg.flow_ctrl = UART_CFG_FLOW_CTRL_NONE ;
     	uart_configure(uart, &cfg);
    
    	uart_irq_callback_set(uart, uart_cb);
    	uart_irq_rx_enable(uart);
    	printk("main function!\n"); //output on UART0, which is default for logging
    	while (1) {
            uart_fifo_fill(uart,buf ,sizeof(buf) );//11 01 01 ED
    
            count=uart_fifo_read(uart,uart_buf,sizeof(uart_buf));
            printf("read  %i\n",count);
    
            k_cpu_idle();
            k_sleep(K_SECONDS(1));
    	}
    }

    I have a question the Arduino code of this sensor works correctly without sending a specific command, why in the code zephyr is obliged to send a specific command to obtain the data in return?

  • I haven't seen the Arduino code so I can't say anything about that unless you share the code. Is the Arduino code also interrupt based?

    Looking at your code, it looks like you're disabling uart irq tx in your callback without enabling it again, any reason for this? Also you are using code in your main function that is supposed to be used in callbacks. I would recommend trying to use a UART API that is not interrupt based to test that you are able to communicate with the sensor.

    -Einar

  • Here is the Arduino code.

    #include <Wire.h>
    
    void setup() {
      Serial.begin(9600);
    }
    
    void loop() {
      typedef unsigned char u8;
      typedef unsigned int u16;
      int inByte;
      u8 temp;
      u8 i, j, o2[12];
      u16 o2c, o2f, o2t; //Define oxygen concentration, flow rate and temperature
    
      //When character arrive over the serial port ..
      if (Serial.available()) {
      // wait a bit for the entire message to arrive
      delay(100);
        // read all the available characters
        while (Serial.available() > 0) {
          inByte = Serial.read();
          //---Receiving part---
          if ((o2[0] == 0x16) && (o2[1] == 0x09) && (o2[2] == 0x01)) //Determine if the first two bytes are received correctly, I is the global variable
          {
            o2[i] = inByte;       
            i++;
          }
          else           //If one of the first three bytes received is incorrect, the first two bytes will be judged
          {
            if ((o2[0] == 0x16) && (o2[1] == 0x09))
            {
              if ( inByte == 0x01)   
              {
                o2[2] =  inByte;   
                i++;
              }
              else                                
              {
                i = 0;                
                for (j = 0; j < 12; j++)          
                {
                  o2[j] = 0;
                }
              }
            }
            else     
            {
              if (o2[0] == 0x16)
              {
                if ( inByte == 0x09)
                {
                  o2[1] =  inByte; 
                  i++;
                }
                else        
                {
                  i = 0;                
                  for (j = 0; j < 12; j++)          
                  {
                    o2[j] = 0;
                  }
                }
              }
              else     
              {
                if ( inByte == 0x16) 
                {
                  o2[0] =  inByte; 
                  i++;
                }
                else         
                {
                  i = 0;                 
                  for (j = 0; j < 12; j++)         
                  {
                    o2[j] = 0;
                  }
                }
              }
            }
          }
         //---Receiving part---
    
    
    
          if (i == 12)   //Data received complete, start calibration
          {
            temp = 0;
            for (j = 0; j < 12; j++)
            {
              temp += o2[j];
            }
            if (temp == 0)     //Check passed, calculate oxygen concentration, flow, temperature value
            {
              o2c = o2[3] * 256 + o2[4];     //Oxygen concentration
              o2f = o2[5] * 256 + o2[6];     //Oxygen flow value
              o2t = o2[7] * 256 + o2[8];     //Oxygen temperature
            }
    
            
    
            i = 0;                             
            for (j = 0; j < 12; j++)           //Initialize array
            {
              o2[j] = 0;
            }
          }
        }
      }
    
    //--O2
    Serial.print("O2 : ");
    Serial.print(o2c/100);
    Serial.print(o2c/10%10);
    Serial.print(".");
    Serial.print(o2c%10);
    Serial.println("%");
    
    //--Flow
    Serial.print("Flow : ");
    Serial.print(o2f/10%10);
    Serial.print(".");
    Serial.print(o2f%10);
    Serial.println("L/min");
    
    //--Temperature
    Serial.print("Temp : ");
    Serial.print(o2t/100);
    Serial.print(o2t/10%10);
    Serial.print(".");
    Serial.print(o2t%10);
    Serial.println("Celcius");
    delay(2000);
    }

Related