0

I'm trying to turn on/off a output or switch a relay etc by controlling the RTS or DTR pin of my RS232 signal. I've created a script in C that switches my DTR or RTS flag on/off but I'm not getting any difference in my output on my serial port to terminal adapter(see image below):

enter image description here

The structure of my RS232 is as follows:

enter image description here

As the image describes, the RTS signal is on pin 8, when I flag this to "on" and i measure between pin 1(ground) and pin 8(RTS) im getting 3V. When I switch it back to off it remains staying at 3V, so nothing changed when I'm toggling DTR or RTS.

Does anyone know what I'm doing wrong?

UPDATE

I've tried the code below(I think it matches @Vincent Achard's answer). This does not work, when I measure between pin 1(ground) and pin 6(5v output) this remains 5V while running the script. Also when I measure between pin 1(ground) and ping 8(RTS) this remains 2.8V while running the script. Does anyone see any mistakes in this code?

enter image description here

Thanks in advance!

NielsStenden
  • 345
  • 2
  • 7
  • Well if you can switch your dtr, just plug that to the signal in of your relay. – Vincent Achard Dec 17 '19 at 08:31
  • I can set my DTR signal high or low and confirm this by checking it, however this will not give me any signals on the output of my serial port. Pin 1-6 stays 5V(supply, see document) and pin1-8(RTS) gives me 3V. – NielsStenden Dec 17 '19 at 08:37
  • How can you set your DTR signal high and low (and checking it) without having any signal on the pin? I misunderstand particularly the checking part, which I consider being able to turn on a LED. If you cannot turn on a LED, how do you check that your DTR pin reacts to your code? – Vincent Achard Dec 17 '19 at 08:47
  • Sorry, its my RTS pin. But i check this pin in code, its pin 8 if u see the documentation link. I connect to my ttyO0 first, then i set the pin by using tiocmbis, i check using tiocmget than i use tiocmbic to set it to 0 and i check again. Output of my script: set high -> check(is high) -> set low -> check(is low). However the output on my pins are all the same everytime i check, pin 1-6 is 5V and pin 1-8 is always 3V. – NielsStenden Dec 17 '19 at 08:56
  • OK. So please reformat your post, this is misleading: "I've created a script in C that switches my DTR signal": if the voltage is the same, it does not switch your signal. And the most relevant part of your question is your ioctl C code versus the voltage result you get. Starting there, we will be able to better help you as it will lye in the scope of 'linux serial port programming'. (The HMI part is irrelevant, it could be a cheap usb to serial dongle, the question would be the same). – Vincent Achard Dec 17 '19 at 09:04
  • Great. Now: your code. I guess you use something like ioctl(fd, TIOCMSET, &ctl); where ctl looks like TIOCM_DTR or TIOCM_RTS ? Correct me if I'm wrong. (And it would be great to have your code in the post it would help). If this is the case, what is your fd? – Vincent Achard Dec 17 '19 at 11:41
  • I see you use tiocmbis. I don't know it well but from what i read in your comment, your problem might be the device you are connecting to. It should be a (node)/(special file) like /dev/ttyUSB0 or so, that represents your serial port device to the kernel. /dev/tty0 might not be the right node. – Vincent Achard Dec 17 '19 at 11:56
  • Its ttyO0 which is linked to ttyS0, I tested this with my scope. I wrote data to this port to test it with my oscilloscope. – NielsStenden Dec 17 '19 at 14:55
  • @VincentAchard I deleted my code on accident, I only got the .exe.. But yeah i connect to my ttyO0 which is linked to my ttys0. I check if connection is set and if connection is set I set the DTR or RTS flag on with TIOCMBIS. After that I check if the flag is set by using TIOCMGET and when its set I set it back off with TIOCMBIC. – NielsStenden Dec 17 '19 at 14:58
  • I used to do that using ioctls: fd=open(dev,O_RDWR); ioctl(fd, TIOCMSET, &controlbits); sleep(1); close(fd); From my notes it seems consistent with what you get: without the sleep(1) the pin would go to its default level (3V). There was a trick on the circuit: I did not use a regular relay. – Vincent Achard Dec 17 '19 at 20:12

1 Answers1

0

The DTR and RST pins on a serial interface do not act like GPIOs: their level will not stay high or down.

I could override this behavior by modifying the kernel tty driver to get a permanent non default state:

file: drivers/tty/tty_port.c

in the

function tty_port_shutdown() 

replace

tty_port_lower_dtr_rts(port);

by

tty_port_raise_dtr_rts(port); 

maybe some easier solutions exist???

Vincent Achard
  • 340
  • 1
  • 5
  • Give me one second to try this, looks awesome! – NielsStenden Dec 18 '19 at 07:18
  • This code gives me a "Segmentation fault" – NielsStenden Dec 18 '19 at 07:43
  • Look the updated post, I think this matches the code u written right? Sorry I cant copy from my VM somehow, therefore i took screenshot. – NielsStenden Dec 18 '19 at 09:16
  • Yes it matches. You get a segfault at which point? – Vincent Achard Dec 18 '19 at 09:34
  • I fixed the segmentation fault. The code I updated in my post works fine but I'm not getting any difference in my outputs when i measure between these :(pin1 -> pin6) or (pin1 -> pin8) while running the code. – NielsStenden Dec 18 '19 at 09:37
  • Could it be some tty setting? I wonder why you use the noctty flag? – Vincent Achard Dec 18 '19 at 13:32
  • From another tutorial, this is my first week with Linux. Let me try without ctty flag? Rest of settings are correct? – NielsStenden Dec 18 '19 at 13:49
  • OK really sorry I did not read my notes correctly... I had to modify the kernel driver to get a permanent switch... Might be a little hard to recompile a kernel in your case? – Vincent Achard Dec 18 '19 at 14:56
  • 1
    On linux, just opening a serial tty (eg. with `exec 7 –  Dec 18 '19 at 16:06
  • @VincentAchard I try this solution, give me a moment – NielsStenden Dec 19 '19 at 07:16
  • The code u u wrote looks like c, in both maps "driver" and "drivers" are not any files who end with .c. My kernel version is 3.10.12 btw – NielsStenden Dec 19 '19 at 09:19
  • @NielsStenden the voltages you get don't look like your port is a rs-232 / is in rs-232 mode. If it were and `ttyO0` really were your serial port, this simple shell command would raise _both_ DTR and RTS and lower them after 3 seconds: `exec 7 –  Dec 19 '19 at 18:05
  • Any luck? Maybe you should buy a cheap usb to serial to do some tests on a /dev/ttyUSB that is known to work. They cost 5US$ only. – Vincent Achard Dec 20 '19 at 08:54