View previous topic :: View next topic |
Author |
Message |
Ttelmah
Joined: 11 Mar 2010 Posts: 19477
|
|
Posted: Tue Oct 08, 2019 6:10 am |
|
|
Agreed wholeheartedly.
Even testing with a reel of cable, does not match what happens in the
real world. The ground differential that exists between buildings for
example is not present in such a test configuration.
I must admit if I was trying to do this, I think what I would do is have
an isolated supply (these little inverter modules are easy), and just implement
a single line pulled up to this supply and driven down using the transistor
outputs of optocouplers. The receive would be driven only when the line
is driven low. This way there would be protection from voltage differentials
on the line, and protection for both the outputs and inputs. A few hundred
bps, is a much more sensible rate to try for and much more likely to work.
If you think of the likely capacitance of 200' of cable. (probably 12pF/ft,
so 2.4nF), to give a slew rate to support 57600bps, is going to require
a very significant drive current.... |
|
|
beaker404
Joined: 24 Jul 2012 Posts: 163
|
|
Posted: Tue Oct 08, 2019 10:02 am |
|
|
tried setting up a MAX232 that connected to the Laptop serial port, then connected two wires to the PIC which has a MAX232 chip on it.
Just did this to get the dual MAX232 scheme to work. It did not. only thing that works is connecting the laptop directly to the PIC via one MAX232.
Seems like it should be simpler that this. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9215 Location: Greensville,Ontario
|
|
Posted: Tue Oct 08, 2019 11:55 am |
|
|
hmmm.. I think every device you add to the chain inverts the signals....so '0's become '1's and vice versa.
That's something I'd have to check using pencil and paper.....
Jay |
|
|
beaker404
Joined: 24 Jul 2012 Posts: 163
|
|
Posted: Tue Oct 08, 2019 3:01 pm |
|
|
tried sending a PM, messages sit in the outbox, never show up in the sent folder so not sure they were delivered. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9215 Location: Greensville,Ontario
|
|
Posted: Tue Oct 08, 2019 3:51 pm |
|
|
I've not got any in the past 3 hrs.... |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
Posted: Tue Oct 08, 2019 5:53 pm |
|
|
I don't think Ttelmah has pop-ups turned on for PMs, because his response
is always slow. He may only learn of a PM if he checks his email. So give
it time. |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19477
|
|
Posted: Wed Oct 09, 2019 1:45 am |
|
|
Not particularly.
Main thing is timezones....
Message arrived at 12.22am my time. It's first thing in the morning for me
now and I have just sent a circuit. |
|
|
beaker404
Joined: 24 Jul 2012 Posts: 163
|
|
Posted: Wed Oct 09, 2019 2:33 pm |
|
|
A bit more on this topic, Admins, advise if I should just start a new thread as now the discussion is shifting to more software. Or specifically software dealing with new hardware.
I have the circuit number 1 with the 4.7K resistors and Schottky diodes working. Here is the problem, data is really glitchy even when I slow it down to 4800 baud. I am thinking it is due to my not properly handling the data I transmit coming right back to me. So, I disabled INT_RDA before a fprintf statement and then enable it back afterwards. Still glitchy and choppy.
Here is my serial handler routine. Crude, but gets the basic task it needs to done.
Code: | void parse_message() {
// "$GX#" is format for requesting a gain value.
// "$SNXXXXXX#" is format for requesting SN change.
// "$ARM#" arms the control waiting for a trigger event.
unsigned int32 digit_1 = 0; // 100000's digit
unsigned int32 digit_2 = 0; // 10000's digit
unsigned int32 digit_3 = 0; // 1000's digit
unsigned int32 digit_4 = 0; // 100's digit
unsigned int32 digit_5 = 0; // 10's digit
unsigned int32 digit_6 = 0; // 1's digit
char ch = '\0';
switch(serial_buffer[1])
{
case 'T': // Abort the control sequence
{
terminate_flg = 1; // 6-16-2012
break;
} // end case 'T' for abort sequence
case 'A': // Start button pressed on host panel.
{
if((serial_buffer[2] == 'R')&&(serial_buffer[3] == 'M')) { // message is 'ARM'
arm_acq_flg = 1; // set the ARM flag for ACQ to get ready and start taking pre-trigger data.
delay_ms(1000); //10-4-19
}
else { // message was corrupt, blank it out reset the receive buffer
arm_acq_flg = 0;
} // end arm case
} // end case 'A' ARM command
case 'G': // Gain requested
{
if(serial_buffer[2] == '0') { // Gain = 1;
opamp_gain = 1;
}
if(serial_buffer[2] == '1') { // Gain = 2;
opamp_gain = 2;
}
if(serial_buffer[2] == '2') { // Gain = 5;
opamp_gain = 5;
}
if(serial_buffer[2] == '3') { // Gain = 10;
opamp_gain = 10;
}
if(serial_buffer[2] == '4') { // Gain = 20;
opamp_gain = 20;
}
if(serial_buffer[2] == '5') { // Gain = 50;
opamp_gain = 50;
}
if(serial_buffer[2] == '6') { // Gain = 100;
opamp_gain = 100;
}
if(serial_buffer[2] == '7') { // Gain = 200;
opamp_gain = 200;
}
if(serial_buffer[2] == '8') { // Gain = 500;
opamp_gain = 500;
}
if(serial_buffer[2] == '9') { // Gain = 1000;
opamp_gain = 1000;
}
gain_flg = 1;
serial_buffer[0] = '\0';
break;
} // end gain case
case 'S': // serial number case $SN123456#
{
if(serial_buffer[2] == 'N') { //$SN
if((serial_buffer[3] != '#')) { // got to be a number.
if(isdigit(serial_buffer[3])) { // process digit_1 if buffer location is a 0 .. 9 digit
ch = serial_buffer[3];
digit_1 = convert_2_num(ch);
digit_1 = digit_1 * 100000;
} // end digit_1 if
} // end '#' '\0' if
if((serial_buffer[4] != '#')) { // got to be a number.
if(isdigit(serial_buffer[4])) { // process digit_2 if buffer location is a 0 .. 9 digit
ch = serial_buffer[4];
digit_2 = convert_2_num(ch);
digit_2 = digit_2*10000;
} // end digit_2 if
} // end '#' '\0' if
if((serial_buffer[5] != '#')) { // got to be a number.
if(isdigit(serial_buffer[5])) { // process digit_3 if buffer location is a 0 .. 9 digit
ch = serial_buffer[5];
digit_3 = convert_2_num(ch);
digit_3 = digit_3*1000;
} // end digit_3 if
} // end '#' '\0' if
if((serial_buffer[6] != '#')) { // got to be a number.
if(isdigit(serial_buffer[6])) { // process digit_4 if buffer location is a 0 .. 9 digit
ch = serial_buffer[6];
digit_4 = convert_2_num(ch);
digit_4 = digit_4 * 100;
} // end digit_4 if
} // end '#' '\0' if
if((serial_buffer[7] != '#')) { // got to be a number.
if(isdigit(serial_buffer[7])) { // process digit_5 if buffer location is a 0 .. 9 digit
ch = serial_buffer[7];
digit_5 = convert_2_num(ch);
digit_5 = digit_5*10;
} // end digit_5 if
} // end '#' '\0' if
if((serial_buffer[8] != '#')) { // got to be a number.
if(isdigit(serial_buffer[8])) { // process digit_6 if buffer location is a 0 .. 9 digit
ch = serial_buffer[8];
digit_6 = convert_2_num(ch);
digit_6 = digit_6*1;
} // end digit_6 if
} // end '#' '\0' if
SN_word = digit_1 + digit_2 + digit_3 + digit_4 + digit_5 + digit_6;
write_SN_to_EEPROM(); // write out int32 SN to EEPROM
fprintf(SERIAL,"SN SAVED\n\r");
send_probe_SN();
}
break;
} // end serial number case
default: // default case
{
gain_flg = 0;
break; // end case default case
}
} // end switch
} // end parse message
|
Dirty code for sure, need to do some cleanup here, but for now need to work on the one wire serial challenge. Open for comments on how to make this routine handle the looped back data of every transmitted character. |
|
|
newguy
Joined: 24 Jun 2004 Posts: 1907
|
|
Posted: Wed Oct 09, 2019 2:54 pm |
|
|
It's not sufficient to disable INT_RDA during a transmit. The UART is still capturing data, but you simply aren't handling it as it arrives. When your transmit routine is complete, code a
Code: | while(kbhit()) {
[read and discard awaiting received characters here]
}
clear_interrupt(INT_RDA);
enable_interrupts(INT_RDA); |
This will clean up things a bit, but in order to reduce glitches more you're probably going to be forced to slow down your baud rate even more. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9215 Location: Greensville,Ontario
|
|
Posted: Wed Oct 09, 2019 4:45 pm |
|
|
OK, reduce baudrate to 300. Remember you've got 200 ft. of 'wire' to deal with. Put scope on wire at both ends and SEE what the datastream looks like. Send continuous 'U's. Pretty sure that looks like a squarewave, so easy to see and confirm nice clean edges. If it's good, up to 600, test, OK, up to 1200,..etc.
There's not much point in cleaning up the software if the hardware is 'glitchy'. You may need to consider RS-485 or some other system. I know +-50 volts can go 15 miles on questionable copper.
Jay |
|
|
Ttelmah
Joined: 11 Mar 2010 Posts: 19477
|
|
Posted: Wed Oct 09, 2019 10:54 pm |
|
|
You don't post your #use RS232, or your #INT_RDA.
Both are important. Ideally #INT_RDA should be staying enabled, but
it needs to be writing the data somewhere else than the buffer you are
trying to interpret, during the transmission.
So have a flag bit. Set it during the transmit (and remember that the
transmission continues for a couple of character times after the printf
completes), and when it is set have the #INT handler throw away the
received characters. |
|
|
temtronic
Joined: 01 Jul 2010 Posts: 9215 Location: Greensville,Ontario
|
|
Posted: Thu Oct 10, 2019 5:13 am |
|
|
I'm thinking you should be able to use the ATOL32() function for you lengthy 'serial number' function ?
It may or may not be 'tighter' code, perhaps try it, dump the listing and see ??
Jay |
|
|
|