View previous topic :: View next topic |
Author |
Message |
js-bascom
Joined: 21 Mar 2013 Posts: 14
|
Posted: Sat Apr 19, 2014 11:54 am Post subject: rs485 modbus master (my fault!) |
|
|
I'm messing around with the above (2.0.7.5 demo) and I made some changes to the code to suit the board I want to use. The board uses a M324p.
Does Makemodbus support PORTC.6 as a Rs485dir pin or is it limited to the one shown on the demo code? I can't seem to get the direction pin to toggle during transmission, and as you have guessed, I get no communications with the slaves. The slaves are working and use freemodbus for the firmware with a PC program called Modview which I have purchased a while ago while doing some boards for a client.
Relevant code snippets just in case I messed up: Code: | Config Print1 = Portc.6 , Mode = Set ' specify RS-485 and direction pin
Rs485dir Alias Portc.6 'make an alias
Config Rs485dir = Output 'set direction register to output
Rs485dir = 0 ' set the pin to 0 for listening | I have also changed the parity to NONE because that's what the slave boards use. Code: | 'configure the second UAR for RS485/MODBUS. Make sure all slaves/servers use the same settings
Config Com2 = 9600 , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0 |
(BASCOM-AVR version : 2.0.7.5 , Latest : 2.0.7.7 ) _________________ John Samperi
Ampertronics Pty. Ltd.
www.ampertronics.com.au
* Electronic Design * Custom Products * Contract Assembly
Last edited by js-bascom on Mon Apr 21, 2014 12:40 am; edited 1 time in total |
|
Back to top |
|
|
albertsm
Joined: 09 Apr 2004 Posts: 5913 Location: Holland
|
Posted: Sat Apr 19, 2014 1:23 pm Post subject: |
|
|
the demo is not limited to a pin, just to :
- size
- not allowed for commercial apps
- no lib source
- no support
so the port pin should work BUT : did you try if you can actually can control that port pin ?
- jtag fuse? , wire mistake, other hardware connected, etc. _________________ Mark |
|
Back to top |
|
|
js-bascom
Joined: 21 Mar 2013 Posts: 14
|
|
Back to top |
|
|
js-bascom
Joined: 21 Mar 2013 Posts: 14
|
Posted: Sun Apr 20, 2014 11:00 am Post subject: |
|
|
Quote: | so the port pin should work | So I messed around a bit , proved that there was nothing wrong with my hardware by putting in some code which sends stuff to the RS485.
And of course the BASCOM code DOES NOT handle PC6 (Rs485dir) AT ALL. I understand if the demo version is not supposed to work but at least be honest about it.
Manually driving Rs485dir gets the addressed slave to blink and "responds", this works. Code: | Rs485dir = 1
Print #1 , Makemodbus(2 , 3 , 1 , 1); ' slave 2, function 3, start address 1, 1 word
Waitms 2
Rs485dir = 0 |
Once I understand how to do a bit test for TXC1 in UCSR1A with BASCOM I will be able to remove the 2 seconds delay after sending. _________________ John Samperi
Ampertronics Pty. Ltd.
www.ampertronics.com.au
* Electronic Design * Custom Products * Contract Assembly |
|
Back to top |
|
|
Frankeman
Joined: 11 Aug 2004 Posts: 948 Location: the Netherlands
|
Posted: Sun Apr 20, 2014 1:19 pm Post subject: |
|
|
Quote: | I understand if the demo version is not supposed to work but at least be honest about it. |
Ai now you have ruined someones day
There is no difference between the demo and the commercial version in the means of functionality.
Only the maximum compiled size is differend. |
|
Back to top |
|
|
albertsm
Joined: 09 Apr 2004 Posts: 5913 Location: Holland
|
Posted: Sun Apr 20, 2014 11:15 pm Post subject: |
|
|
Quote: | And of course the BASCOM code DOES NOT handle PC6 (Rs485dir) AT ALL. I understand if the demo version is not supposed to work but at least be honest about it. Smile |
no it is as i said. but 2075 is a bit old now, and when i check something, i always use the latest version. when it does not work in 2075 it is a bug and present in the 2075 full version as well.
But as i was looking at modbus lately i saw that the pin toggles as intended. at least in the code.
Did you check with a scope? When the direction of the pin is set as you shown all print statements set the direction, then print, wait till the uart buffer tx flag is set, then switch back the direction.
when you show a more complete piece of code that can be tested i can check it. _________________ Mark |
|
Back to top |
|
|
js-bascom
Joined: 21 Mar 2013 Posts: 14
|
Posted: Sun Apr 20, 2014 11:15 pm Post subject: |
|
|
Quote: | you have ruined someones day | My apologies to anyone who's day has been ruined by my comment.
Quote: | There is no difference between the demo and the commercial version | I'm sorry to disagree, at least in this instance or if that's true then there is a major bug in the code which I doubt.
Having worked with micros for 30+ years, about 13 years with AVRs, I went back to basics and plugged a M162 into the STK500 along with a RS485 breakout board just like the demo version shows.
REGARDLESS of which pin on PORTB is selected for Rs485dir in the source file, PB1 is ALWAYS used for that function. Now it is possible that there is some library settings (which is not available for the demo version) which needs to be be also changed to be able to use another pin. That's OK but then the honest answer to my OP is that the demo ONLY works as described and not say that it should work with PC6 as I was trying to do.
Anyway I'll drop this now, no point wasting anymore time. _________________ John Samperi
Ampertronics Pty. Ltd.
www.ampertronics.com.au
* Electronic Design * Custom Products * Contract Assembly |
|
Back to top |
|
|
js-bascom
Joined: 21 Mar 2013 Posts: 14
|
Posted: Sun Apr 20, 2014 11:21 pm Post subject: |
|
|
Sorry Mark, we seemed to have posted at the same time. Here is the full code which I have modified to work with on of my boards. As I said I don't really want to spend anymore time with this but if there is a bug it would be nice to fix it.
EDIT Can't post the code, there must be some trick to it like there is on AVRfreaks.
2nd edit OK it will take a file. _________________ John Samperi
Ampertronics Pty. Ltd.
www.ampertronics.com.au
* Electronic Design * Custom Products * Contract Assembly |
|
Back to top |
|
|
albertsm
Joined: 09 Apr 2004 Posts: 5913 Location: Holland
|
Posted: Sun Apr 20, 2014 11:40 pm Post subject: |
|
|
well i get this :
;##### PRINT #1 , MAKEMODBUS(2 , 3 , 1 , 1);
Sbi $0008,6 ;##### SET PORTC.6
^^ set portc.6
then the printing
and
Cbi $0008,6 ;##### RESET PORTC.6
so at least in 2077 it works. i will have a look at 2075 tomorrow. _________________ Mark |
|
Back to top |
|
|
js-bascom
Joined: 21 Mar 2013 Posts: 14
|
|
Back to top |
|
|
js-bascom
Joined: 21 Mar 2013 Posts: 14
|
Posted: Mon Apr 21, 2014 2:46 am Post subject: |
|
|
And of course the fact that I wasn't getting the same message was another commented out line!
Now I have the code talking to 2 slaves, not getting what I really want with function 3 code (reading from a board with 16 inputs) but I'm not getting the 8x error after the returned slave address.
Function 6 is working very well talking to a board with with 20 outputs, I need to send 2 lots of addresses as there doesn't seem to be an auto increment.
It works with delays between packets of 15 ms so I have doubled that to be sure. The data out is simply W incremented, lots of pretty flashing LEDs, yep soooo nerdy! Code: | Waitms 30 ' delay
Print #1 , Makemodbus(7 , 6 , 40000 , W); ' slave 2, function 6, address 40000 , value of w
Waitms 30
Print #1 , Makemodbus(7 , 6 , 40001 , W); ' slave 2, function 6, address 40001 , value of w
W = W+1 |
_________________ John Samperi
Ampertronics Pty. Ltd.
www.ampertronics.com.au
* Electronic Design * Custom Products * Contract Assembly |
|
Back to top |
|
|
albertsm
Joined: 09 Apr 2004 Posts: 5913 Location: Holland
|
Posted: Mon Apr 21, 2014 2:03 pm Post subject: |
|
|
no problem, John. I appreciate you are so honest to admit the mistake.
All functions should work equally well (or bad).
During the years the code was changed/improved a few times. The problems/fixes were :
- there was no wait for the tx done flag, and when switching direction it can mean the slave does not get the whole byte. but we are talking pre 2075.
- then there was a tx ready flag check, but this flag need to be cleared after that, otherwise it will not be set the next time.
- and clearing this flag requires a read modify write for some micros since the ucsra register is not a flag register and contains other flags. thus this resulted in code that disable ints, then resets the flag and re-enables global ints if they were enabled.
- as far as i can tell 2075 should be fine.
I feel there should not be any delay after the print. but it depends on the slave. and when sending lot of data, is there still a moment where you process the result? in such a case a delay in transmission could be desirable. _________________ Mark |
|
Back to top |
|
|
js-bascom
Joined: 21 Mar 2013 Posts: 14
|
Posted: Mon Apr 21, 2014 10:22 pm Post subject: |
|
|
Quote: | I feel there should not be any delay after the print. | I think the slaves choke if I send 2 packet to the same slave immediately. Actually Giovanni DeLuca (Italian BASCOM forum) suggested a minimum of 100ms but it seems that the slaves (which run freemodbus) can keep up with about 15ms.
Now I'm trying to get the buffered input working so that I can the return data from one of the slaves (16 inputs) and forward it to another slave (20 outputs) and maybe add a 3rd slave for fun. It sort of works sometimes but not reliably yet, I guess I will do a lot more reading before shooting my mouth off!
To add to my confessions and embarrassment I think that the STK500, which I used in my 2nd attempt with the M162, is not working too well in ISP mode with BASCOM for some reason but the STK500.exe window shuts down too quickly to see what's going on. It did work when I loaded the code as originally posted with PB1 but further attempts at programming after I changed the bit in portb may have failed at times giving the feeling that there was a bug somewhere. Programming with the JTAG Mk2 and Studio 4.18 had no problems.
I'm adding this in case someone falls into the same trap. _________________ John Samperi
Ampertronics Pty. Ltd.
www.ampertronics.com.au
* Electronic Design * Custom Products * Contract Assembly |
|
Back to top |
|
|
js-bascom
Joined: 21 Mar 2013 Posts: 14
|
Posted: Fri Apr 25, 2014 8:27 am Post subject: |
|
|
And just to complete the thread I'm posting my "final" code.
It has been a lot of fun playing with BASIC, I feel 30 years younger! Last time I did any work with BASICA for DOS was about 20 years ago.
The code exchanges information between 2 complementary boards, one with 16 inputs and the other with 20 outputs, the last 4 outputs follows a variable which gets incremented at every loop and and the first 16 outputs mimic the 16 inputs of the other board.
It also exchanges information between the master's 8 inputs and 8 outputs with a 3rd board which also has the same number of inputs and outputs.
The "conversations" are printed to the terminal to see what was send and received.
As mentioned the slaves use Freemodbus code, the registers' addresses are a bit high but they can be changed to suit. I hope this is useful to someone.
Code: | '-----------------------------------------------------------------------------------------
'name : rs485-modbus-master.bas
'copyright : (c) 1995-2008, MCS Electronics
'purpose : demo file for MAKEMODBUS
'micro : Mega324p
'suited for demo : yes
'commercial addon needed : no
'Modified by John Samperi 2014
'-----------------------------------------------------------------------------------------
$regfile = "m324pdef.dat" ' specify the used micro
$crystal = 18432000 ' 18.432MHz
$baud = 19200 ' use baud rate
$hwstack = 42 ' default use 42 for the hardware stack
$swstack = 40 ' default use 40 for the SW stack
$framesize = 40 ' default use 40 for the frame space
$lib "modbus.lbx" ' specify the additional library
'the libray will call a routine for UAR0,UART1,UAR2 and/or UAR3.
'when you get an error message that a label is not found with _SENDCHAR3 or _SENDCHAR4 then add these labels
'when you later use these routines you might get a duplicate label error and then you need to remove them
Config Print1 = Portc.6 , Mode = Set ' specify RS-485 and direction pin
Rs485dir Alias Portc.6 'make an alias
Config Rs485dir = Output 'set direction register to output
Rs485dir = 0 'set the pin to 0 for listening
' Output port is B
Ddrb = &HFF
Strobe Alias Portc.7
Config Strobe = Output 'set direction register to output
Strobe = 0
'configure the first UART for RS232
Config Com1 = Dummy , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0
'configure the second UAR for RS485/MODBUS. Make sure all slaves/servers use the same settings
Config Com2 = 9600 , Synchrone = 0 , Parity = None , Stopbits = 1 , Databits = 8 , Clockpol = 0
'use OPEN/CLOSE for using the second UART
Open "COM2:" For Binary As #1
'dimension some variables
Dim A As Byte
Dim B As Byte
Dim Count As Byte
Dim Modbus_packet_size As Byte
Dim Low_switches As Byte
Dim High_switches As Byte
Dim Switches_16 As Word
Dim W As Word
Dim Modbus_packet(15) As Byte
Declare Sub Get_modbus_packet
Declare Sub Print_modbus_packet
Const Serial1_buffer_size = 20
W = 0000
Enable Interrupts
Config Serialin1 = Buffered , Size = Serial1_buffer_size
Print "" : Print "RS-485 MODBUS master"
Do
' Waitms 1000 'add to slow down packet printing ' delay
Print "" : Print "Poll slave 2, 16 inputs > ";
Print #1 , Makemodbus(2 , 3 , 40000 , 2); ' slave 2, function 3, start address 40000, 2 bytes
Gosub Get_modbus_packet
Low_switches = Modbus_packet(4)
High_switches = Modbus_packet(3)
Switches_16 = Makeint(low_switches , High_switches )
Gosub Print_modbus_packet
Print "" : Print "Send to slave 3, lower 16 outputs > ";
Print #1 , Makemodbus(3 , 6 , 40000 , Switches_16); ' slave 4, function 6, address 40000, Switches_16
Gosub Get_modbus_packet
' Process return packet if needed
Gosub Print_modbus_packet
Print "" : Print "Send to slave 3, upper 16 outputs > ";
Print #1 , Makemodbus(3 , 6 , 40001 , W); ' slave 4, function 6, address 40001, value of w
Gosub Get_modbus_packet
' Process return packet if needed
Gosub Print_modbus_packet
Print "" : Print "Poll slave 4, 8 inputs > ";
Print #1 , Makemodbus(4 , 3 , 40008 , 6); ' slave 3, function 3, start address 40008, 6 bytes
Gosub Get_modbus_packet
' Process return packet if needed
Gosub Print_modbus_packet
'Mimic status of low 8 switches from slave 2 locally
Portb = Modbus_packet(3)
'Latch data
Strobe = 1
Strobe = 0
A = Not Pina
Switches_16 = Makeint(0 , A)
Print "" : Print "Send to slave 4, 8 outputs > ";
Print #1 , Makemodbus(4 , 6 , 40009 , Switches_16); ' slave 4, function 6, address 40009, Switches_16
Gosub Get_modbus_packet
' Process return packet if needed
Gosub Print_modbus_packet
Print ""
W = W + 1
Loop
Sub Get_modbus_packet
' Restart buffer
Clear Serialin1
'Wait for Modbus packet to come in
Waitms 30
Modbus_packet_size = _rs_bufcountr1
Count = 0
Do
If Ischarwaiting(#1) = 1 Then 'was there a char?
A = Inkey(#1) 'get it
Modbus_packet(count) = A
Incr Count
End If
Loop Until Count = Modbus_packet_size
End Sub
Sub Print_modbus_packet
Count = 0
Do
Print Hex(modbus_packet(count));
Incr Count
Loop Until Count = Modbus_packet_size
Print " ";
End Sub
End |
And by the way Mark if I do manage to get a job for a commercial project you can be sure that I will purchase a license. _________________ John Samperi
Ampertronics Pty. Ltd.
www.ampertronics.com.au
* Electronic Design * Custom Products * Contract Assembly |
|
Back to top |
|
|
albertsm
Joined: 09 Apr 2004 Posts: 5913 Location: Holland
|
Posted: Sat Apr 26, 2014 9:35 pm Post subject: |
|
|
thanks for sharing. the commercial version comes with a modbus slave as well. _________________ Mark |
|
Back to top |
|
|
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum You cannot attach files in this forum You cannot download files in this forum
|
|