您好,我按照例子,写的程序,发布消息没问题,mqtt服务器可以接受,但UNO却无法接受订阅消息,是哪里出了问题?
[mw_shl_code=arduino,true]
#include <OneWire.h>
#include <U8glib.h>
#include <MsTimer2.h>
#include <WiFiEsp.h>
#include <WiFiEspUdp.h>
#include <WiFiEspClient.h>
#include <PubSubClient.h>
#include <SoftwareSerial.h>
#define MqttServer_IP "10.1.3.172" // 连接服务器
#define MqttServer_PORT 1883 // 连接服务器8234
#define WIFI_AP "z"
#define WIFI_PASSWORD "3333222222"
#define ID "10002"
int status = WL_IDLE_STATUS; // the Wifi radio's status
float celsius;
bool flag_second;//每秒触发一次,用于每隔1秒,串口发送一次数据
byte addr[8];
byte pwmpin=5;//UNO中只能用 3,5,6,9,10,11
String inString="";//输入指令字符 SET_PWM=52
String PWM_valStr;
byte PWM_val=255;//0-255,越大,速度越慢
const byte interruptPin = 3;//脉冲输入IO ,UNO中断引脚只有 pin2 (int0) 和 pin3(int1)
byte Val = 0; //设置变量 Val,计数 (服务器散热风扇,12V下最高风速时,162转/s)
byte Val_n = 0; //每秒多少转
unsigned int RPM = 0; //每分多少转
OneWire ds(13); // on pin 10 (a 4.7K resistor is necessary)
U8GLIB_KS0108_128 u8g(6, 7, 8, 9, 10,11, 12, A0, A1, A2, A3, A4, A5 );
//U8GLIB_KS0108_128 u8g(6(pin 7), 7(pin 8), 8(pin 9), 9(pin 10), 10(pin 11),11(pin 12), 12(pin 13), A0(pin 14) A1(pin 6), A2(pin 15), A3(pin 16), A4(pin 4), A5(pin 5) );
// 8Bit Com: D0..D7: 8,9,10,11,4,5,6,7 en=18, cs1=14, cs2=15,di=17,rw=16
//YXD-12864BG液晶屏1.Vss 2.+3.3V 3.背光调节 4.RS Comand/Data Input 5.R/W Read/Write Signal Input 6.E 7.D0 8.D1 9.D2 10.D3 11.D4 12.D5 13.D6 14.D7 15.CS1 16.CS2 17.RES 18.Vout 19.LED +5V 20.GND
SoftwareSerial Serial_wifi(2, 4); // RX, TX
// 初始化以太网客户端对象
WiFiEspClient espClient;
// 初始化MQTT库PubSubClient.h的对象
PubSubClient client(espClient);
void setup(void) {
Serial.begin(9600);
attachInterrupt(digitalPinToInterrupt(interruptPin), count, FALLING);//FALLING RISING CHANGE
InitWiFi(); // 连接WiFi
client.setServer( MqttServer_IP, MqttServer_PORT); // 连接WiFi之后,连接MQTT服务器
client.setCallback(callback);
client.subscribe("v1/devices/me/IntelligentFan_CMD");
pinMode(pwmpin, OUTPUT);
// 中断设置函数,每 1000ms 进入一次中断
MsTimer2::set(1000, rpm_count);
MsTimer2::start();
}
void loop(void) {
initDs18b20();//ds18b20中间取温度需要 750ms 用delay太浪费所以,程序分成两部分,运行其他
status = WiFi.status();
if ( status != WL_CONNECTED) {
while ( status != WL_CONNECTED) {
Serial.print("[loop()]Attempting connect to WPA SSID: ");
Serial.println(WIFI_AP);
// 连接WiFi热点
status = WiFi.begin(WIFI_AP, WIFI_PASSWORD);
delay(500);
}
Serial.println("[loop()]Connected to AP");
}
if ( !client.connected() ) {
reconnect();
}
client.loop();
/*
while(Serial.available()>0){
char inChar= Serial.read();
inString +=(char) inChar;
delay(10);
}
if(inString!=""){
Serial.print("Input String:");
Serial.println(inString);
PWM_valStr=inString.substring(8);//SET_PWM=52
PWM_val=PWM_valStr.toInt();
Serial.println(PWM_val);
// analogWrite(pwmpin, PWM_val);
inString="";
}
*/
analogWrite(pwmpin, PWM_val);//设置pwm,
//每秒发送一次数据
if(flag_second==1){
getandSendTemperatureAndRPMData();
//每秒标记
flag_second=0;
}
draw();
//delay(500);
getDs18b20WenDu();
}
void initDs18b20(void) {
byte i;
if ( !ds.search(addr)) {
//Serial.println("No more addresses.");
ds.reset_search();
delay(250);
return;
}
//Serial.print("ROM =");
//for ( i = 0; i < 8; i++) {
//Serial.write(' ');
//Serial.print(addr, HEX);
// }
if (OneWire::crc8(addr, 7) != addr[7]) {
Serial.println("CRC is not valid!");
return;
}
//Serial.println();
ds.reset();
ds.select(addr);
ds.write(0x44, 1); // start conversion, with parasite power on at the end
//delay(1000); // maybe 750ms is enough, maybe not
// we might do a ds.depower() here, but the reset will take care of it.
}
void getDs18b20WenDu(void) {
byte i;
byte present = 0;
byte data[12];
present = ds.reset();
ds.select(addr);
ds.write(0xBE); // Read Scratchpad
for ( i = 0; i < 9; i++) { // we need 9 bytes
data = ds.read();
//Serial.print(data, HEX);
//Serial.print(" ");
}
int16_t raw = (data[1] << 8) | data[0];
byte cfg = (data[4] & 0x60);
// at lower res, the low bits are undefined, so let's zero them
if (cfg == 0x00) raw = raw & ~7; // 9 bit resolution, 93.75 ms
else if (cfg == 0x20) raw = raw & ~3; // 10 bit res, 187.5 ms
else if (cfg == 0x40) raw = raw & ~1; // 11 bit res, 375 ms
//// default is 12 bit resolution, 750 ms conversion time
celsius = (float)raw / 16.0;
//Serial.print(" T = ");//Temperature
//Serial.println(celsius);
//Serial.print(" Celsius, ");
}
/*
*
* 把温度、转速发送到MQTT服务器上去
*
*/
void getandSendTemperatureAndRPMData()
{
Serial.println("Collecting data.");
//温度
Serial.print("T=");//Temperature
Serial.print(celsius,2);
//转速
Serial.print("; V=");
Serial.print(Val_n);//Val是1秒钟转多少圈
Serial.print("; RPM=");
RPM=60*Val_n;
Serial.print(RPM);//转换成rpm,Val是1秒钟转多少圈,rpm=60*val
Serial.println(";");
String celsiusString = String(celsius);
String Val_nString = String(Val_n);
String RPMString = String(RPM);
// 构建一个 JSON 格式的payload的字符串
String payload = "{";
payload += "\"temperature\":"; payload += celsiusString; payload += ",";
payload += "\"Val\":"; payload += Val_nString;
payload += ",\"RPM\":"; payload += RPMString;
payload += "}";
// Send payload
char attributes[100];
//payload.toCharArray( attributes, 100 );
payload.toCharArray( attributes, 90 );
// boolean publish(const char* topic, const char* payload);
client.publish( "v1/devices/me/IntelligentFan", attributes );
Serial.print("[publish]-->>");
Serial.println( attributes );
}
void InitWiFi()
{
// 初始化软串口,软串口连接ESP模块
Serial_wifi.begin(9600);
// 初始化ESP模块
WiFi.init(&Serial_wifi);
// 检测WiFi模块在不在,宏定义:WL_NO_SHIELD = 255,WL_IDLE_STATUS = 0,
if (WiFi.status() == WL_NO_SHIELD) {
Serial.println("WiFi not present");
while (true);
}
Serial.println("[InitWiFi]Connect AP ...");
// 尝试连接WiFi网络
while ( status != WL_CONNECTED) {
Serial.print("[InitWiFi]Attempt connect WPA SSID: ");
Serial.println(WIFI_AP);
// Connect to WPA/WPA2 network
status = WiFi.begin(WIFI_AP, WIFI_PASSWORD);
delay(500);
}
Serial.println("[InitWiFi]Connected AP");
}
/**
*
* MQTT客户端断线重连函数
*
*/
void reconnect() {
// 一直循环直到连接上MQTT服务器
while (!client.connected()) {
Serial.print("[reconnect]Connect MQTT Server ...");
// 尝试连接connect是个重载函数 (clientId, username, password)
//boolean connect(const char* id, const char* willTopic, uint8_t willQos, boolean willRetain, const char* willMessage);
//client.connect(ID, "v1/devices/me/telemetry_will",0, 0,"willdead");
if ( client.connect(ID, "v1/devices/me/IntelligentFan_will",0, 0,"willdead") ) {//该设备的遗愿信息,如果mqtt服务器收不到信号,就会向订阅号发willdead信息
//if ( client.connect(ID, NULL, NULL) ) {
client.subscribe("v1/devices/me/IntelligentFan_CMD");
Serial.println( "[DONE]" );
} else {
Serial.print( "[FAILED][mqtt connect error code=" );
Serial.print( client.state() );
Serial.println( " :retrying in 3 seconds]" );// Wait 5 seconds before retrying
delay( 3000 );
}
}
}
void callback(char* topic, byte* payload, unsigned int length) {
Serial.print("Message arrived [");
Serial.print(topic);
Serial.print("] ");
for (int i=0;i<length;i++) {
Serial.print((char)payload);
}
Serial.println();
}
void draw(void) {
u8g.firstPage();
do {
//u8g.setColorIndex(1);
u8g.setFont(u8g_font_unifont);
//u8g.setFont(u8g_font_osb21);
u8g.drawStr( 0, 40, "T:");
u8g.setFont(u8g_font_unifont);
u8g.setPrintPos(16, 40);
u8g.print(celsius, 2);
//u8g.drawBitmapP ( 0 , 0 , 2 , 16 , bitmap_z);
//u8g.drawBitmapP ( 17 , 0 , 2 , 16 , bitmap_s );
//u8g.drawBitmapP ( 33 , 0 , 2 , 16 , bitmap_j );
u8g.drawStr( 0, 52, "V:");
u8g.setFont(u8g_font_unifont);
u8g.setPrintPos(16, 52);
u8g.print(Val_n);
u8g.drawStr( 0,64, "RPM:");
u8g.setPrintPos(32, 64);
u8g.print(RPM);
} while ( u8g.nextPage() );
}
void count() {
Val += 1;
}
void rpm_count() {
Val_n = Val;
flag_second=1;
Val = 0;//输出速度结果后清零,记录下一秒的触发次数
}[/mw_shl_code]
|