Trying to get CP341 to talk ASCII

Johnny T

Member
Join Date
Jul 2003
Location
Fife, Scotland
Posts
642
Hi all

I started a similar topic to this a while back when I was struggling to talk to some motors. The problem was that the card I had at the time (CP340) wouldn't go up to 19200 baud on ASCII. I've now got a CP341 card and so need help setting it up.

I've spent a day and a half now messing around with it and I'm getting nowhere... I shall explain what I've done and where I'm up to in the hope that you can point in me in the right direction...

Right.. here goes...

I'm trying to communicate with a MAC servo motor. I can talk to it via a free little program they give you called MACregIO. When you send a command to the motor via this program, it shows you the string that it is sending.

Here's what the manual says...

 
Block Name Protected [font=DEKEEP+Arial,Bold](1) [/font]Example Description
[font=DEHIBG+Arial]<Write> [/font][font=DEHIBG+Arial]No 52[/font][font=DEHIBG+Arial]h,52h,52h [/font][font=DEHIBG+Arial]Write command[/font]
[font=DEHIBG+Arial]<Address> [/font][font=DEHIBG+Arial]Yes [/font][font=DEHIBG+Arial]07h,F8h (Address 7) [/font][font=DEHIBG+Arial]The address of the MAC motor[/font]
[font=DEHIBG+Arial]<RegNum> [/font][font=DEHIBG+Arial]Yes [/font][font=DEHIBG+Arial]05h,FAh (RegNum 5) [/font][font=DEHIBG+Arial]The register number to write to[/font]
[font=DEHIBG+Arial]<Len> [/font][font=DEHIBG+Arial]Yes [/font][font=DEHIBG+Arial]02h,FDh (Len = 2) [/font][font=DEHIBG+Arial]The number of data bytes[/font]
[font=DEHIBG+Arial]<Data> [/font][font=DEHIBG+Arial]Yes [/font][font=DEHIBG+Arial]E8h,17h, 03h,FCh [/font][font=DEHIBG+Arial](Data = 1000) [/font][font=DEHIBG+Arial]The data to write to the register[/font]
[font=DEHIBG+Arial]<End> [/font][font=DEHIBG+Arial]No [/font][font=DEHIBG+Arial]AAh, AAh [/font][font=DEHIBG+Arial]Command termination[/font]




The protected bit means that you send a byte and its opposite so that the motor can double check its correct.

So.. here's an example of a string I want to send...

 
Write 230,000 (38270h) to register 3 (32 bit) to the MAC motor with address 2.[font=DEJIAO+Humanst521BT][/font]

Transmit:52h,52h,52h - 02h,FDh - 03h,FCh - 04h,FBh - 70h,8Fh,82h,7Dh,03h,FCh,00h,FFh - AAh, AAh




I've installed the CP341 module to my rack (its in slot 5) and I've called FB8 (P_SND_RK) with the following info...

 A I 0.5
FP M 99.5
= L 20.0
BLD 103
AN M 90.0
JNB _001
CALL "P_SND_RK" , DB114
SF :=
REQ :=L20.0
R :=
LADDR :=272
DB_NO :=80
DBB_NO :=0
LEN :=20
R_CPU_NO:=
R_TYP :=
R_NO :=
R_OFFSET:=
R_CF_BYT:=
R_CF_BIT:=
DONE :=M100.3
ERROR :=M100.4
STATUS :=MW104
_001: NOP 0



Basically I'm one-shotting I0.5 and saying to send 20 bytes of information starting from DB80.DBB0 (as far as I understand it).

Now... In DB80 I have the following....


Address Struct Value
0.0 BYTE 0
1.0 BYTE 52
2.0 BYTE 52
3.0 BYTE 52
4.0 WORD 2FD
6.0 WORD 3FC
8.0 WORD 4FB
10.0 WORD FF
12.0 WORD FF
14.0 WORD FF
16.0 WORD FF
18.0 WORD AAAA



This should send the position of 0 (ie. the four words of 00FF) to motor address 2.

But.... nothing

The M100.3 (DONE) marker comes on when I trigger FB8 but apart from that I get nothing.

I've routed the output into HyperTerminal and I get a string out of the CP341 but something tells me its not working correctly.

It seems like sometimes when I change the DB80 its still sending the same string out (do you need to somehow re-initialise the card before every send?)

The motors aren't doing diddly squat. I've tried using all DWORDS in the datablock, all BYTES, all WORDS.. combinations of the above. I've tried reversing the string ie. FD02 instead of 2FD but all to no avail.

I've exhausted everything I can think of so thought I'd put the question to the experts on here in the hope that someone can steer me in the right direction.

By the way, I've tried the example program (in the Step7 Examples folder) for P2P comms using ASCII but I just get the SF light on my PLC and it doesn't work for some reason (I did change the CP341 address in the program as it requests - but still SF light).

Has anyone got an example program, preferably written in Ladder, that could maybe help me out?
Does anyone know if there is some extra setting up/initialisation that needs to be done with the CP341 for correct use?

Many thanks for your help

Cheers

JT :)
 
Last edited:
Right.... eventually.... I've got the thing talking.

I can flick inputs and get the drive to move. I've connected another drive (ie. two now) and I can fire 4 different inputs and get the first and second drive to go 1 rev clockwise or anticlockwise depending on the input pressed.

I have another question for you but first just a note on how I did it in case anyone else has the same problem in the future. The problem was in the format of the datablock. I ended up having to send the same info I listed in my previous post but put it in the datablock in the following format:

 
BYTE
BYTE
BYTE
BYTE
BYTE
BYTE
WORD
WORD
WORD
WORD
WORD
WORD
WORD



Strange but true...

Anyways... next question is this....

The end project will consist of 16 motors and I want to be able to talk to them all simultaneously (or as near as possible to simultaneous with a serial link).

How can I call FB8 (the send block) fast and cyclically to step through 16 strings that it needs to send out.

Is it best to call it 16 times separately and give it 16 different instance db's or can I do it with one instance db??

Is it best to have all the info I need to send in one db and use the DBB offset to step through it all or is it best to have 16 different DB's and call DB8 with a different DB every time??

Are there restrictions on how many times you can call FB8 and how fast it can fire out the ASCII strings??

I'm basically looking for the best way to approach the problem...

Any ideas most appreciated...

Cheers

JT :)

PS. Just another quick question... whenver I disconnect the comms lead to the motors the CP341 goes to SF. However, when I reconnect it doesn't automatically reset itself. I have to power off and on again to get the SF light to go out. Is there a way of making it self-reset when comms are reconnected??
 
Johnny T said:
I ended up having to send the same info I listed in my previous post but put it in the datablock in the following format:

 
BYTE
BYTE
BYTE
BYTE
BYTE
BYTE
WORD
WORD
WORD
WORD
WORD
WORD
WORD



Strange but true...

Hmmm, I don't think I buy that Johnny. The data types in the DB are completely irrelevent (this can be seen if you dig into FB8). All it does is start at your starting point (DBB0) and send each byte (in your case, 20) one by one. I'm more inclined to believe that you were formatting the message incorrectly, and when you arranged the data types the way you did, the byte sequence happened to be right. Typically, when I use ASCII data, I just make an array of 1024 CHAR variables in my DB (this allows me to monitor the message online) and fill the array with my message. You could do the same thing by copyin your values about to the CHAR array and send the message. Or, since it's working, you can leave it the way it is, but I wanted to make sure you understand that the data format doesn't matter.

Are there restrictions on how many times you can call FB8 and how fast it can fire out the ASCII strings??

You have to wait for the FB8 call to finish before you send the next string. The time it takes to finish depends on the length of the string. The CP341 sends data in 34 byte increments, so in your case you should be able to send and complete the transmission in one scan. If you had a 340 byte message, it would take 10 scans. So, that is the real world limit.

The end project will consist of 16 motors and I want to be able to talk to them all simultaneously (or as near as possible to simultaneous with a serial link).

How are you doing this? You are using one CP card, right? Are the drives linked together, and you send a drive ID as part of the message? If so, you should be able to put all of the messages together and send it all at once with one IDB. But, due to the limitation above, it will not go out in one "burst". I've never seen this be a problem before, but you'll have to give it a try.

Is there a way of making it self-reset when comms are reconnected??

I wrote my own S/R functions instead of using the Siemens functions, so I'm not sure if they provide a way to reset the card automatically (is the error bit set in this condition?). But in my case, I monitor Byte 10 of the CP card PI area. For instance, if your card starts at Byte 512, then I would monitor Byte 522. This byte will contain the status bits of the card. Look at this byte online with and without the error condition and you will be able to tell which one you need to use to send a reset to the card.
 
S7Guy

Many thanks for the info.

I didn't understand myself why it wouldn't work with the DB formatted the other way. You are right.. it might have been a mistake on my part, or perhaps the way the bytes are received by the motor (ie. a high byte/low byte problem).

I'll investigate it further when I've got the rest of it running.

I'll try your suggestion about sending one long string out and see what happens.

I'll also analyse the input bytes and see what changes when I lose comms.

You are right in your deduction that the motor address is part of the string and all the motors are linked together...

Will post back results on how I get on.

Thanks again :)

JT
 
S7Guy,

You were right... (as though it was in any doubt).. I changed the format of the datablock to all WORDs and it worked fine.

I've set up a 500ms pulse that indexes through the 16 motors and sends out the relevant data, seems to be working ok at the moment..

Will post back with anything else I find

Cheers

JT :)
 
Right.. another problem I've come across is receiving the data that has been sent back.

I've set up FB 8 to send the data and I'm using the 'done' bit to energise FB 7 to receive the data sent back from the servo motor.

The data I'm expecting back is 11, 11, 11 (in hex) to tell me the drive has received the commands and is doing its' stuff.

However, all I receive back is the full string that I have sent.

I wondered if maybe I'm just 'receiving' whats in the buffer of the CP341 card and not what has been sent back from the drive?

Ideally I want to send the relevant positional data to the first drive, then listen and check I've got 11h,11h,11h back, then send the positional data to the second drive, listen, then the third drive etc etc etc

My question is this...

Once I have sent the data to the drive with FB 8, do I need to 'clear' the CP341 or something before I can then receive data back?

Is there something I'm not doing correctly?

The FB 8 and FB 7 (send and receive) are both giving me the 'done' bits correctly, its just that the data is not what I expect.

I've scoured the servo manual and that is adamant that I should receive 11,11,11 so I'm assuming that this is a problem at the CP341 end??

Any ideas?

Cheers

JT :)
 
Where are you putting the received data? Is it a different area than the send data? I doubt that you are receiving the data in the buffer, as the CP card just doesn't work like that.

Try calling FB7 unconditionally instead of using the done bit. I'll take a look at FB7 later and see if anything else looks obvious.
 
S7Guy

I'm putting the received data in a different datablock.

I'll try your suggestion though and call the received block unconditionally...

Cheers

JT
 
Having the receive function block as 'unconditional' didn't make a difference...

I'm still just receiving the full string that I send out (or thats how it appears anyway)

If you do get a chance to have a delve through FB7 and see anything that could shed some light on it then that would be most appreciated.

Cheers

JT :)
 
Ok, can you try something out? When you send the message, include a byte that you increment on each transmission. Then, see if you are getting each message back by looking at the value of the byte.

Also, you can try using hyperterminal to send yourself a message to see if that works.

I can't imagine a scenario where the card would receive its own message (not saying it's impossible, but it just doesn't seem likely) because it uses two different SFCs (SFC 58 and 59) for the send/receive.
 
S7Guy

I tried just putting the card into recieve (ie. blocking off the transmit block and having an unconditional receive). I then sent some stuff from hyperterminal and it received it ok.

However, when I transmit normally to the motors it still receives the transmitted string.

I'll do some more experimenting with it and see if I can figure anything else out...

Cheers

JT
 

Similar Topics

I can't seem to get the Panel View Plus 7 standard edition to downgrade to V_11, when I check the AB downloads and compatibility websites for this...
Replies
1
Views
135
Hi I used to be able to launch PLCsim without any problem. Now it tells me " STEP 7 Professional Licence is required to simulate this PLC"...
Replies
15
Views
521
Hello! When trying to load the hardware configuration I get error 0050-133 2 2458, check the diagnostic buffer. When checking the buffer, it says...
Replies
4
Views
183
We have a keg check weigher that that lost a fight to a forklift. The scale was previously a Systec IT3000, which was the only PROFIBUS slave...
Replies
5
Views
673
Back
Top Bottom