实现两个RS485传感器数据采集(基于原子哥代码)

本篇文章在基于本人第一篇文章(基于STM32 RS485传感器数据采集(参考正点原子部分代码)_stm32用rs485代码_做个有理想的程序员的博客-CSDN博客)修改过后 思路和步骤基本一样,我接着讲述不一样的部分

1、需要定义好两个传感器的地址和功能码,避免传输时,数据冲突,造成乱码现象

//主机命令区
u8   SlaverAddr_1=0x01;    // 传感器1
u8   SlaverAddr_2=0x06;     //传感器2
u8   SlaverAddr;

//振动传感器指令 01 03 00 00 00 04 
u8   Fuction_1=0x03;      // 功能码
u16  StartAddr_1=0x00;    //起始地址
u16  ValueOrLenth_1=0x04;  //数据or长度

//油含水率传感器指令 06 03 00 00 00 04 
u8   Fuction_2=0x03;      // 功能码
u16  StartAddr_2=0x00;    //起始地址
u16  ValueOrLenth_2=0x04;  //数据or长度

2、需要添加一个通讯策略,基于一个传感器上添加一个即可。因为两个传感器的功能码不一样,主机需要按顺序访问这两个丛机。

/
//通讯策略
void modbus_rtu(void)  //中断4调用
{	
	static u8 i=0;
//	static u8 j=0;
	switch(i)
	{
		case 0:      //modbus执行命令第一步。
				//RS485_TX_Service();  //向从机发送一个请求。就在此时发送完成TX_RX_SET=1 发送命令完成,定时器T4处理接收到的数据
		    //在此处也可以直接写Master_Service( SlaverAddr, Fuction, StartAddr, ValueOrLenth);
		    //多次通讯结果可以按照类似的封装进行填写
		    
		    if(shock_state == 0)
				{
					Master_Service(0x01);//测振动速度
					shock_state = 1;
				}
				else
				{
					Master_Service(0x06);//测油中含油水分
					shock_state = 0;
				}
				
 	  		if(TX_RX_SET) i=1; //发送,接受命令切换。 0 发送模式 1 接受模式
		    state=1;
				break;
		case 1:     //modbus命令执行第二步。
				RS485_RX_Service();  //执行数据接收 
		    state=2;
		      if(ComErr==0)  //如果什么错误都没有发生
				{
					i=2;//完成命令更换功能码!
				} //一次通讯已经完成
				else   //错误接收后再次准备接收
				{
					i=1;//
					j++;//一个命令发送3次没有应答切换下一个命令
					if(j>=2)
					{
						j=0;
						i=2;
						ComErr=7;  //通讯超时
					}				
				}
				break;
		case 2: //从机地址++	
		    i=0;
		    state=3;
				break;
	}
				
	
}
	

3、从机 功能码01处理的程序添加上

void Master_01_Slove(u8 SlaverAddr_1,u8 Fuction_1,u8 StartAddr_1,u8 ValueOrLenth_1)
{ 
	u16 calCRC;
    RS485_TX_BUFF[0] = SlaverAddr_1;
    RS485_TX_BUFF[1] = Fuction_1;    //modbus 指令码03
    RS485_TX_BUFF[2] = HI(StartAddr_1);  
    RS485_TX_BUFF[3] = LOW(StartAddr_1); 
    RS485_TX_BUFF[4] = HI(ValueOrLenth_1);
    RS485_TX_BUFF[5] = LOW(ValueOrLenth_1);
    calCRC=CRC_Compute(RS485_TX_BUFF,6);
    RS485_TX_BUFF[6]=(calCRC>>8)&0xFF;
    RS485_TX_BUFF[7]=(calCRC)&0xFF;
	RS485_SendData(RS485_TX_BUFF,8);
}

4、然后对传感器采集的数据进行处理,每个传感器采集的数据格式有所不同,有的是单精度浮点数,有的是先低8位,在高8位.

void Modbus_01_Solve(void)
{
	
		u8 rxlen=RS485_RX_CNT;
	    u8 i=0;
			float temp_value=0;
			float X_shock=0,Y_shock=0,Z_shock=0;
		if(rxlen==RS485_RX_CNT&&rxlen)//接收到了数据,且接收完成了
		{
			for(i=0;i<rxlen;i++)
			{
				printf("%13x",RS485_RX_BUFF[i]);	
			}
            printf("n");			
			RS485_RX_CNT=0;		//清零
			
			//温度值	
			temp_value=RS485_RX_BUFF[4]+(RS485_RX_BUFF[3]<<8);
			printf("temp_value=%.1f \r\n",temp_value/10);
			//X_shock
			temp_value=RS485_RX_BUFF[6]+(RS485_RX_BUFF[5]<<8);
			printf("X_shock=%.1f \r\n",X_shock/10);
			
			//Y_shock
			temp_value=RS485_RX_BUFF[8]+(RS485_RX_BUFF[7]<<8);
			printf("Y_shock=%.1f \r\n",Y_shock/10);
			
			//Z_shock
			temp_value=RS485_RX_BUFF[10]+(RS485_RX_BUFF[9]<<8);
			printf("Z_shock=%.1f \r\n",Z_shock/10);
			
		}
		TX_RX_SET=0; //命令完成		
		
}

有什么问题可以直接咨询问,平时回复都比较及时

  • 9
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 10
    评论
好的,下面是一个示例代码,可以帮助您实现RS485传感器组网并将数据通过WiFi上传到OneNet平台。请注意,这只是一个示例代码,您需要根据您的实际情况进行修改。 ```C++ #include <SoftwareSerial.h> #include <WiFiEsp.h> #include <Wire.h> SoftwareSerial RS485Serial(2, 3); //RS485总线连接到Arduino的2号和3号引脚 WiFiEspClient wifiClient; String ssid = "your_SSID"; //WiFi网络的名称 String password = "your_password"; //WiFi网络的密码 String apiKey = "your_apiKey"; //OneNet平台的apiKey String deviceId = "your_deviceId"; //OneNet平台的设备ID void setup() { Serial.begin(115200); RS485Serial.begin(9600); WiFi.init(&Serial); connectWiFi(); } void loop() { //读取传感器数据 float temperature = readTemperature(); //读取温度传感器数据 float humidity = readHumidity(); //读取湿度传感器数据 //将数据上传到OneNet平台 String data = "{\"temperature\":" + String(temperature) + ",\"humidity\":" + String(humidity) + "}"; if (uploadData(data)) { Serial.println("Upload data successfully!"); } else { Serial.println("Upload data failed!"); } delay(10000); //每隔10秒上传一次数据 } //连接WiFi网络 void connectWiFi() { WiFi.begin(ssid.c_str(), password.c_str()); Serial.print("Connecting to "); Serial.print(ssid); while (WiFi.status() != WL_CONNECTED) { delay(1000); Serial.print("."); } Serial.println(); Serial.println("WiFi connected"); } //读取温度传感器数据 float readTemperature() { //发送读取温度传感器数据的命令到RS485总线 RS485Serial.write(0x01); //传感器地址 RS485Serial.write(0x03); //读取命令 RS485Serial.write(0x00); //数据起始地址 RS485Serial.write(0x01); //数据长度 RS485Serial.write(0xC5); //CRC校验码 delay(100); //等待传感器响应 //读取传感器返回的数据 byte data[8]; int i = 0; while (RS485Serial.available()) { data[i] = RS485Serial.read(); i++; } //计算温度值 int rawValue = (data[3] << 8) | data[4]; float temperature = rawValue / 16.0; return temperature; } //读取湿度传感器数据 float readHumidity() { //发送读取湿度传感器数据的命令到RS485总线 RS485Serial.write(0x02); //传感器地址 RS485Serial.write(0x03); //读取命令 RS485Serial.write(0x00); //数据起始地址 RS485Serial.write(0x01); //数据长度 RS485Serial.write(0x9A); //CRC校验码 delay(100); //等待传感器响应 //读取传感器返回的数据 byte data[8]; int i = 0; while (RS485Serial.available()) { data[i] = RS485Serial.read(); i++; } //计算湿度值 int rawValue = (data[3] << 8) | data[4]; float humidity = rawValue / 10.0; return humidity; } //将数据上传到OneNet平台 bool uploadData(String data) { if (wifiClient.connect("api.heclouds.com", 80)) { String postString = "POST /devices/" + deviceId + "/datapoints HTTP/1.1\r\n"; postString += "Host: api.heclouds.com\r\n"; postString += "Content-Type: application/json\r\n"; postString += "api-key: " + apiKey + "\r\n"; postString += "Content-Length: " + String(data.length()) + "\r\n\r\n"; postString += data; wifiClient.print(postString); if (wifiClient.connected()) { while (wifiClient.available()) { String response = wifiClient.readStringUntil('\r'); if (response.indexOf("success") > 0) { wifiClient.stop(); return true; } } } else { Serial.println("Connection failed"); wifiClient.stop(); return false; } } else { Serial.println("Connection failed"); wifiClient.stop(); return false; } } ``` 这个示例代码假设您使用了两个传感器,分别是温度传感器和湿度传感器,它们的地址分别为1和2。您需要根据您实际使用的传感器进行修改。当然,您还需要将WiFi网络的名称、密码、OneNet平台的apiKey和设备ID修改为您自己的。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值