I've been trying to update someone else' software to work on a new machine.
They built a Modbus controller using the Pymodbus library to work with the main software.
The only difference between the original working machine and this new one is that the DAQ is different.
I had assumed going in that this would just mean changing addresses but probably due to my lack of knowledge about Pymodbus this has been very far from the case.
The main issue I am having right now is that is that I am trying to simply communicate with holding registers and the only response I can get back is "(131, 3, Slave Device Busy)".
I am really not sure what to do with this information, It happens as soon as it is started and nothing is able to change it.
Has anyone else had any experience where a device always outputting this same error code?
the DAQ I am using is a Aspar IO Slim Module MOD-ETH
Any advice would be much appreciated.
Thank you
J
(I would attached the code here but it is quite long and I'm not sure a snippet would really help but do let me know if it would be helpful)
Short test code
from pymodbus.client.sync import ModbusTcpClient as ModbusClient
import logging
logging.basicConfig()
log = logging.getLogger()
log.setLevel(logging.DEBUG)
log.debug("Connecting to controller (IP=169.254.54.23, Port 502)")
client = ModbusClient('192.168.1.135', port=502)
59 #client = ModbusClient(method='ascii', port='/dev/pts/2', timeout=1)
60 # client = ModbusClient(method='rtu', port='/dev/ttyp0', timeout=1)
client.connect()
log.debug("Connected to controller (IP=192.168.1.135, Port 502)")
log.debug("Reading Sump Oil Temperature")
rr = client.read_holding_registers(1021, 1, unit=1)
log.debug("Read Sump Oil Temperature")
if rr.function_code > 0x80:
print( "Error has occured!\n" + str( rr.function_code ) + "\n" + str( rr.exception_code ) )
else:
print( rr.getRegister(0) )
client.close()
Response:
DEBUG:root:Connecting to controller (IP=169.254.54.23, Port 502)
DEBUG:root:Connected to controller (IP=192.168.1.135, Port 502)
DEBUG:root:Reading Sump Oil Temperature
DEBUG:pymodbus.transaction:Current transaction state - IDLE
DEBUG:pymodbus.transaction:Running transaction 1
DEBUG:pymodbus.transaction:SEND: 0x0 0x1 0x0 0x0 0x0 0x6 0x1 0x3 0x3 0xfd 0x0 0x1
DEBUG:pymodbus.client.sync:New Transaction state 'SENDING'
DEBUG:pymodbus.transaction:Changing transaction state from 'SENDING' to 'WAITING FOR REPLY'
DEBUG:pymodbus.transaction:Changing transaction state from 'WAITING FOR REPLY' to 'PROCESSING REPLY'
DEBUG:pymodbus.transaction:RECV: 0x0 0x1 0x0 0x0 0x0 0x3 0x1 0x83 0x6
DEBUG:pymodbus.framer.socket_framer:Processing: 0x0 0x1 0x0 0x0 0x0 0x3 0x1 0x83 0x6
DEBUG:pymodbus.factory:Factory Response[131]
DEBUG:pymodbus.transaction:Adding transaction 1
DEBUG:pymodbus.transaction:Getting transaction 1
DEBUG:pymodbus.transaction:Changing transaction state from 'PROCESSING REPLY' to 'TRANSACTION_COMPLETE'
DEBUG:root:Read Sump Oil Temperature
Error has occured!
131
6
Related
I develop a firmware running a ESP32-based custom PCB in a connected battery (hereafter the BATTERY).
Th battery is capable of CANbus connectivity, and I want to take advantage of it to upgrade the firmware.
For this purpose, I took a second PCB (hereafter the UPDATER) which I use to transfer the firmware bin file to the BATTERY.
On the BATTERY, I have FreeRTOS task with a relatively high priority of 9: its responsibility is to wait for the UPDATER incoming message and respond accordingly.
On the other hand, the UPDATER runs a FreeRTOS task that is used to send new firmware bin file chunks of data to the BATTERY. The task also runs at priority 9.
Streamlined exchange protocol is as follows:
UPDATER BATTERY
Start w/ i=0 Start w/ chunkId = 0
| |
loop: |
| |
Take ith 8-byte chunk |
from bin file and |
transmit to battery |
| |
o --------------------------->o
| |
| send current chunkId
| back to UPDATER
| and chunkId++
| |
o< ---------------------------o
|
Read received chunkId
and compare to I
If i != chunkId
then error and stop
Otherwise i++
and 'loop:' till the end
of file is reached
|
Success
The typical firmware bin file size is 1.8MB.
The issue I have, is on the BATTERY, and it is related to the canRx() task for(;;) loop. After a many loops and chunks exchanged, I end up with a watch dog triggered:
E (548436) task_wdt: Task watchdog got triggered. The following tasks did not reset the watchdog in time:E (548436) task_wdt: - IDLE0 (CPU 0)
E (548436) task_wdt: Tasks currently running:
E (548436) task_wdt: CPU 0: btController
E (548436) task_wdt: CPU 1: IDLE1
E (548436) task_wdt: Aborting.
abort() was called at PC 0x401d105c on core 0ELF file SHA256: 0000000000000000Backtrace: 0x40095ac4:0x3ffbffd0 0x40095d3d:0x3ffbfff0 0x401d105c:0x3ffc0010 0x400913f1:0x3ffc0030 0x401e0289:0x3ffd37d0 0x401e085d:0x3ffd37f0 0x400979f2:0x3ffd3820
My task runs on CORE_1 and the code looks like so:
void canRx(void *arg) {
can_message_t rx_frame;
firmwareUpdater.log("FU: Installing high performance canRx task handler");
for (;;) {
if (can_receive(&rx_frame, pdMS_TO_TICKS(20)) == ESP_OK) { // 1000
// Receive
const unsigned id = rx_frame.identifier;
//#if LOG_LEVEL >= LOG_LEVEL_DEBUG
firmwareUpdater.log("FU: CAN <== RX 0x%04x", id);
//#endif
switch (id) {
// Restart smartbox
// == Reboot a device from the smartbox
case CANBUS_CANID_RESTART:
{
// = What deice must be restarted?
byte device = rx_frame.data[0];
switch (device)
{
// Restart smartbox
case CANBUS_DEVICE_SMARTBOX:
pepsr.restart("Requested by CANbus");
break;
default:
firmwareUpdater.error("FU: asked to restart device %02x which is unknown: ignored");
break;
}
break;
}
// Start (over) update process
case FIRMWAREUPDATE_CANID_START_OF_PROCESS:
{
const unsigned fileSize = (rx_frame.data[0] << 24) | (rx_frame.data[1] << 16) | (rx_frame.data[2] << 8) | rx_frame.data[3];
firmwareUpdater.startProcess(fileSize);
}
break;
case FIRMWAREUPDATE_CANID_FIRMWARE_IDENTIFIER:
firmwareUpdater.sendFirmwareBuild();
delay(1000);
firmwareUpdater.sendFirmwareIdentifier();
break;
case FIRMWAREUPDATE_CANID_ADDCHUNK:
firmwareUpdater.addChunk(rx_frame.data, rx_frame.data_length_code);
break;
default:
firmwareUpdater.log("FU: CAN <== RX 0x%04x | Not an ADD CHUNK", id);
break;
}
}
else {
firmwareUpdater.log("FU: CAN: no pending messages");
}
// === VERY IMPORTANT: Let watchdog know we are still there
delay(20);
}
}
#endif
And the task itself is fired as follows:
log("Installing hi speed RX callback");
xTaskCreatePinnedToCore(&canRx, "CAN_rx", 4096, NULL,
//5 //TASK_PRIORITY_REGULAR_5
9 // TASK_PRIORITY_HI_9
, &xCanRxHandle, tskNO_AFFINITY);
As you can see, I tried to transfer control to the scheduler by playing with:
The task priority by taking it down to 5;
Adding extra delay() in the loop;
Reducing the timeout value of the `can_receive() from 1000 down to 20.
But nothing really works: for instance, by increasing the delay()(point 2), I manage to make the transfer more robust but at the expense of an unmanageable total duration.
My bet is that something is fundamentally wrong somewhere.
I need extra thought and help! Thanks in advance.
I've connected YS-IRTM v3.06 IR receiver/transmitter using softuart
like described in the project
For some reason with code below, IR is receiving one byte per single serial write.
I've tried to shield sensor from IR diode in case these two are interfering with each other but with no success.
How to avoid such unexpected behaviour?
s = softuart.setup(9600, 6, 5)
I_HANDLER = tmr.create()
I_HANDLER:register(900, tmr.ALARM_AUTO, function(t)
s:write(encoder.fromHex("a1f1" .. "01fe40"))
end)
I_HANDLER:start()
s:on("data", 3, function(data)
print("INPUT: "..encoder.toHex(data))
end)
Output
INPUT: f1f1f1
INPUT: f1f1f1
INPUT: f1f1f1
....
Nodemcu is
NodeMCU 3.0.0.0 built on nodemcu-build.com provided by frightanic.com
branch: master
commit: 8d091c476edf6ae2977a5f2a74bf5824d07d6183
release: 3.0-master_20200610
release DTS: 202006092026
SSL: false
build type: integer
LFS: 0x0 bytes total capacity
modules: encoder,file,gpio,http,mqtt,net,node,rfswitch,sjson,softuart,tmr,uart,wifi,wifi_monitor
build 2020-08-12 12:12 powered by Lua 5.1.4 on SDK 3.0.1-dev(fce080e)
I'm using a Adafruit Ethernet FeatherWing plugged into an Adafruit Feather 328P and I want to send and receive UDP packets from a Python application. I'm using the stock Arduino UDP code just to see what I'm sending. Here's my Python code:
def write_Arduino(self):
sock_readresp = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock_readresp.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock_readresp.bind((self.config["DEFAULT"]["THIS_IP_ADDRESS"], int(self.config["DEFAULT"]["RECEIVE_PORT"] )))
sock_readresp.settimeout(.2)
MESSAGE = struct.pack("30c", b'0', b'1', b'2', b'3', b'4', b'5', b'6', b'7', b'8', b'9',
b'0', b'1', b'2', b'3', b'4', b'5', b'6', b'7', b'8', b'9',
b'0', b'1', b'2', b'3', b'4', b'5', b'6', b'7', b'8', b'9')
print("Message is {}".format(MESSAGE))
sock_read = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock_read.setblocking(0)
sock_read.bind((self.config["DEFAULT"]["THIS_IP_ADDRESS"], 0))
sock_read.sendto(MESSAGE,(self.config["DEFAULT"]["ARDUINO_IP_ADDRESS"],int(self.config["DEFAULT"]["SEND_PORT"])))
sock_read.close()
My settings are:
THIS_IP_ADDRESS = 192.168.121.1
ARDUINO_IP_ADDRESS = 192.168.121.2
SEND_PORT = 8888
RECEIVE_PORT = 32001
and I've updated the Arduino code to reflect that. When I send this packet, I can confirm it through Wireshark on my PC
I seem to be sending exactly what I think I am. A string of "012345678901234567890123456789" (Wireshark shows the ASCII characters in hex, as seen here). However, receiving it on the Arduino looks like this:
Received packet of size 30
From 192.168.121.1, port 64143
Contents:
012345678901234567890123D6789
The 25th and 26th byte always show up like that, and I'm missing the actual data. What could be going on here?
I am trying to send AT commands to ESP8266 to get connected with internet with the Wifi.
When I am sending AT and AT+RST command on serial monitor then I am getting OK and ready response which seems perfect.
Then I am sending AT+CWLAP to get list of available wifi networks which is also executing correctly.
AT+CWLAP
+CWLAP:(3,"Moto",-42,"a4:70:d6:7a:fa:6c",1,25,0)
+CWLAP:(4,"PRANJAL",-95,"1c:a5:32:3d:f5:c4",1,-16,0)
+CWLAP:(2,"VIHAN",-94,"c8:3a:35:2f:1d:81",1,-21,0)
+CWLAP:(3,"Tenda",-93,"c8:3a:35:20:a9:b1",9,-4,0)
OK
Then I sent AT+CWMODE? which is also perfect.
AT+CWMODE?
+CWMODE:1
OK
Now I am trying to connect ESP8266 with above listed Wifi with this command, it is sending an ERROR on serial monitor.
AT+CWJAP_DEF="Moto","reset1234"
Error
⸮=IRe"Moto","reset1234"
ERROR
Can anyone suggest me what could be the reason of this issue ?
#include "SoftwareSerial.h"
SoftwareSerial esp8266(2, 3); // RX, TX
void setup()
{
Serial.begin(9600); // serial port used for debugging
esp8266.begin(9600); // your ESP's baud rate might be different
}
void loop()
{
if(esp8266.available()) // check if the ESP is sending a message
{
while(esp8266.available())
{
char c = esp8266.read(); // read the next character.
Serial.write(c); // writes data to the serial monitor
}
}
if(Serial.available())
{
delay(10); // wait to let all the input command in the serial buffer
// read the input command in a string
String cmd = "";
while(Serial.available())
{
cmd += (char)Serial.read();
}
// send to the esp8266
esp8266.println(cmd);
}
}
The current official AT command set seems to be documented on https://github.com/espressif/ESP8266_AT/wiki/AT_Description
http://espressif.com/sites/default/files/documentation/4a-esp8266_at_instruction_set_en.pdf
https://www.itead.cc/wiki/ESP8266_Serial_WIFI_Module#AT_Commands
If the module is to be configured as a client, i.e. to connect to an access point, the following AT commands have to be sent (11500 baud 8N1, CR-LF line termination):
AT+RST
AT+CWMODE=3 (1 is "Station" only (wifi client), 3 is mixed mode "Station and Access-Point", both should work)
AT+CWJAP="Moto","reset1234"
AT+CWJAP_CUR="Moto","reset1234" (temporary) or
AT+CWJAP_DEF="Moto","reset1234" (stored)
For reference, a "success story" (ESP8266 module with USB-UART, Software: HTerm, Access Point with WPA2 (both TKIP / CCMP tested)):
AT<\r><\r><\n><\r><\n>
OK<\r><\n>
AT+RST<\r><\r><\n><\r><\n>
OK<\r><\n>
<\r><\n>
ets Jan 8 2013,rst cause:2, boot mode:(3,6)<\r><\n>
<\r><\n>
load 0x40100000, len 1856, room 16 <\r><\n>
tail 0<\r><\n>
chksum 0x63<\r><\n>
load 0x3ffe8000, len 776, room 8 <\r><\n>
tail 0<\r><\n>
chksum 0x02<\r><\n>
load 0x3ffe8310, len 552, room 8 <\r><\n>
tail 0<\r><\n>
chksum 0x79<\r><\n>
csum 0x79<\r><\n>
<\r><\n>
2nd boot version : 1.5<\r><\n>
SPI Speed : 40MHz<\r><\n>
SPI Mode : DIO<\r><\n>
SPI Flash Size & Map: 32Mbit(512KB+512KB)<\r><\n>
jump to run user1 # 1000<\r><\n>
<\r><\n>
??r?d?l<18>?<31><\0><\f>?l`<3>??s?l?<28>?<19>?<4><4><4>$ <2>??r?$<4>??<27>?<4><4>ll`<3>r$?<18>?"<\0>????"<4>l?cs|<\f>?`?22???<27>BB<18>c??o??<18>NN?<16><2><\0><2>d$??<2>d??<\0>?<4>d??<\0>ll????d??l`<2>?<2>N?<\0>????"<4>d??<28>p<4><4><2><2>???"b<4>$<4>?"prlrl<\r><\n>
Ai-Thinker Technology Co. Ltd.<\r><\n>
<\r><\n>
ready<\r><\n>
WIFI DISCONNECT<\r><\n>
AT+CWMODE?<\r><\r><\n>+CWMODE:3<\r><\n>
<\r><\n>
OK<\r><\n>
AT+CWJAP_CUR="Moto","reset1234"<\r><\r><\n>
WIFI CONNECTED<\r><\n>
WIFI GOT IP<\r><\n>
<\r><\n>
OK<\r><\n>
AT+CIFSR<\r><\r><\n>+CIFSR:APIP,"0.0.0.0"<\r><\n>
+CIFSR:APMAC,"00:00:00:00:00:00"<\r><\n>
+CIFSR:STAIP,"0.0.0.0"<\r><\n>
+CIFSR:STAMAC,"00:00:00:00:00:00"<\r><\n>
<\r><\n>
OK<\r><\n>
AT+GMR<\r><\r><\n>AT version:1.1.0.0(May 11 2016 18:09:56)<\r><\n>
SDK version:1.5.4(baaeaebb)<\r><\n>
Ai-Thinker Technology Co. Ltd.<\r><\n>
Jun 13 2016 11:29:20<\r><\n>
OK<\r><\n>
This also works with mode=1.
Major rewrite.
Questions and ideas to test:
what is your module firmware version?
access point issues (e.g. MAC address restrictions)?
power supply good?
might there be any old configuration or other code running on the module?
what is the byte code of ⸮ in the error message - Is it two bytes 0x2E2E?
are you using the Arduino serial monitor for communication?
in contrast to my comment, maybe the arduino does have an influence (timing?). Try to rule this out by
doing the pass-through character-based instead of line-based, e.g.:
(end of list, no code possible otherwise:)
loop(){
if( esp8266.available() )
Serial.write(esp8266.read());
if( Serial.available() )
esp8266.write(Serial.read());
}
keeping the AVR in reset and connecting the ESP8266 serial lines directly to the USB-UART converter
Alright! I just tried to connect with different wifi and it got connected with it. It was some kinda issue with mobile hotspot.
Im having this problem just when i answer the phone and then hangup, but asterisk does not detect the hangup while AMD is detecting ?
Asterisk 11.11
-- Executing [09XXXXXXXX#appel-sortant:10] NoOp("Local/09XXXXXXXX#appel-sortant-40f9;2", "Next = 0") in new stack
-- Executing [09XXXXXXXX#appel-sortant:11] Set("Local/09XXXXXXXX#appel-sortant-40f9;2", "GLOBAL(NEXT)=0") in new stack
== Setting global variable 'NEXT' to '0'
-- Executing [09XXXXXXXX#appel-sortant:12] Dial("Local/09XXXXXXXX#appel-sortant-40f9;2", "SIP/09XXXXXXXX#forfait-ovh,20,gtr") in new stack
== Using SIP RTP CoS mark 5
-- Called 09XXXXXXXX#forfait-ovh
-- SIP/forfait-ovh-00000000 is ringing
-- SIP/forfait-ovh-00000000 is making progress passing it to Local/09XXXXXXXX#appel-sortant-40f9;2
-- SIP/forfait-ovh-00000000 answered Local/09XXXXXXXX#appel-sortant-40f9;2
> Channel Local/09XXXXXXXX#appel-sortant-40f9;1 was answered.
-- Executing [s#appel-sortant:1] Playback("Local/09XXXXXXXX#appel-sortant-40f9;1", "silence/1") in new stack
-- <Local/09XXXXXXXX#appel-sortant-40f9;1> Playing 'silence/1.gsm' (language 'en')
== Spawn extension (appel-sortant, 09XXXXXXXX, 12) exited non-zero on 'Local/09XXXXXXXX#appel-sortant-40f9;2'
-- Executing [s#appel-sortant:2] AMD("SIP/forfait-ovh-00000000", "") in new stack
-- AMD: SIP/forfait-ovh-00000000 09XXXXXXXX (null) (Fmt: 64)
-- AMD: initialSilence [2500] greeting [1500] afterGreetingSilence [800] totalAnalysisTime [5000] minimumWordLength [100] betweenWordsSilence [50] maximumNumberOfWords [3] silenceThreshold [256] maximumWordLength [5000]
-- AMD: Channel [SIP/forfait-ovh-00000000]. Changed state to STATE_IN_SILENCE
-- AMD: Channel [SIP/forfait-ovh-00000000]. HANGUP
[Aug 31 09:19:35] NOTICE[32712]: pbx_spool.c:349 attempt_thread: Call completed to Local/09XXXXXXXX#appel-sortant
extensions.conf
exten => s,1,Playback(silence/1)
exten => s,n,AMD()
exten => s,n,NoOp(AMDSTATUS = ${AMDSTATUS})
exten => s,n,GotoIf($[${AMDSTATUS}=MACHINE]?appel-sortant-mach,s,1:appel-sortant-humn,s,1)
I resolved the problem implementing the hangup handler.
Hangup Handlers
Asterisk DO detect hangup on called party ALWAYS.
There are no way prevent that.
Check your provider/FXO gate, probably it just not detect hangup.