G30 COM2 Issues

@Justin The level shifter is just a USB to Serial cable for testing purposes. I am not sure I understand what you are saying.

The G30 is 3v3 and the Co-Pro is 5v therefor for reliable comms you need a level shiftier between the 2 processors.

Since you have no clock signal carrier in UART it can be a little harder to know for sure what the data is supposed to be. But its not very hard. You just start at the beginning and go up one period (1 / 57600) at a time and write down whether it is high or low. The transitions in the message should make it pretty obvious where the boundaries between bits exist, even when there is no transition. And don’t forget start and stop bits. If your scope can draw a vertical line that you can move around it makes it much easier. It’s a tedious task but for such short messages I wouldn’t say there is much skill required.

But of course why bother if the problem doesn’t appear in the PCB.

You asked about COM 2 and pull-ups. It is standard for the driver (sender) to manage the line. So the G30 should be pulling up and pulling down the line when necessary while the RX of the receiver is a simple HIGH-Z input. Maybe somewhere in here lies your issue. Maybe the lines can’t keep a stable voltage because of something pulling it low when it isn’t supposed to.

I have to ask. It is all grounded together right?

You shouldn’t have to level shift anything to communicate with a 3.3 V G30 and a 5V Coprocessor. I do it all the time. You can shift the 5V down with a simple divider if you are worried about that. Many pins on the G30 are 5V tolerant. It’s all in the spec.

While in most cases, the voltage shown for minimum “high” signal on a 5v part shouldn’t be an issue when driving to 3v3, if there’s any voltage drop (poorly performing 3v3 supply rail, other circuit issues) you can see issues - if you want a robust solution, then as Justin said, I’d err on the side of caution and incorporate level shifting between the two. [quote=“jwizard93, post:43, topic:20894”]
I have to ask. It is all grounded together right?
[/quote]

Absolutely another major question. Differences in GND reference can lead to “seeing” different signals because voltage levels are lower. But on a scope you’d still see the digital offset, just not with the output voltage you expect.

My suspicion is always that there’s a combination of issues going on - hardware and software. You need test code that is just echoing what it receives and doing nothing else, or just sending a known string - that way you exactly know what the scope trace should look like.

This one is the most relevant to me - it’s your code. Handling strings and state machines is a non-trivial code task. I’m betting code is your largest problem - another reason to prove your hardware works with just a standard message being repeatedly sent, or looping back.

To make these kinds of captures sensible with UARTs, you need to tell us what TX is, not just what colour trace TX is. Are you saying it’s TX on the G30? Or are you saying it’s TX on the 5v co-pro? Or is it TX on a USB-UART? Your clarity will help speed up our troubleshooting.

Plus, for scope captures, you can use a digital IO pin to trigger capture if you’re having issues capturing the right signal… not sure that this is really an issue for you, but this image doesn’t seem to have captured enough bits for ++ADDR +CR, and from the scrolly graph at the top it looks like you don’t have the memory to capture more characters?

The scope is connected to TX and RX of the coprocessor. The second scope picture should definitely be the full bits for ++addr\r but I think you are right about the first picture - I used tera term so I probably missed the characters as I typed them and only captured me hitting enter (not a memory issue, it is a matter of how the terminals send each character to the buffer as you type).

This code has been tested with an FT232 and works fine. I can put a break right where the message is sent to check everything and it all looks good.

commport.Write(Encoding.UFT8.GetBytes(message),0,message.length);

where message = ++addr\r and GetBytes(message) = [43, 43, 118, 101, 114, 13]

I asked about pullups because I know the G30 does need a pull up on one of the COM2 pins but I assume the development board comes with this installed. If not, then that is my problem.

The 3.3V USB to serial cable was able to communicate with the 5V coprocessor so I do not think that is the issue, but still a possibility.

The weirdest part is it works some of the time.

please point to what section of the datasheet says that.

so what’s different? That’s what you should be looking at first as it’s the more obvious area that will lead to discoveries… and I assume you mean “it was tested with a G30 and FT232 in place of my coprocessor” ? really, you need to tell us the whole story not the shortened version… :wink:

1 Like

The difference here is that the FT232 is replaced by a PIC18F2550. The PIC handles serial communication on one side (G30) and translates this to GPIB communication. I can communicate perfectly fine from a PC ---->GPIB----->PIC------->G30. I can also get messages across from G30---->PIC---->GPIB----->PC but the latter has a caveat. I am not sure if it is just the ++commands that cause the failure or any messages sent from the G30 in general. I have only replicated the failure when a ++command is sent. These commands are handled by the PIC to change configuration settings. When it receives a ++command, I get a response on the G30 but then the PIC stops communicating with the GPIB. This only occurs when the G30 is used to send commands, if I go PC—>PIC with the USB to serial cable, I can send ++commands over and over and the PIC never stops working. Now with the G30 sending the ++commands, I have about a 50% chance of it causing a failure.

My mistake, it is COM1 RX that requires a 10k pullup, not COM2

who wrote the PIC code? My inkling is that it’s likely to be a combination of G30 code, PIC code and possibly 5v/3v3 level shifting error. You haven’t talked about your G30 code at all, and while you think your testing was complete/comprehensive, it seems you were only working at “typed” speeds not machine speeds, so I would focus on robustness of that code first…

Yes, perhaps if you tried putting a large break between the transmission of each character then you might find that the performance matches that of the TeraTerm, typed version.

The PIC code was written by this guy "GPIB to USB converter"

He helped me change his set up so that it goes to serial instead of the FTDI chip. This code has been tested for years and works good. I even sent him one of my GPIBs to test it with and it works. The only difference in setups is the G30.

I have talked about the G30 code, it is all posted further up in this thread. The meat of the code is:

commport.Write(Encoding.UFT8.GetBytes(message),0,message.length);

where message = ++addr\r and GetBytes(message) = [43, 43, 118, 101, 114, 13]

So to clarify, it works in the scenario of “typed” speeds but machine speed does not seem to work, at least in that one direction. I will try transmitting one character at a time from the G30 instead of writing a whole buffer at once. Thank you for the suggestion. Let me know if there is anything else you can think of

Well in my stubbornness, coming from studying c++ in college, I only used Tera Term once to try and rid myself of netmf and quickly realized how foolish that path was :sweat_smile: (big fan now) (Or maybe I used it to get netmf back on my chip, can’t remember)

So I’m not knowledgeable: is CR on Tera Term equivalent to ‘\r’ from the G30? It kinda looks like it is on the scope but I can’t say for sure. Not sure if it matters but crossed my mind.

Dude, I just don’t get it. You’re talking about one line of code - I agree, that’s hard to screw up. But are you READING anything on the G30’s serial line ? Care to draw a block diagram and typical flows for those of us who are visual? (this will allow someone here, should they choose to, to replicate it with their own hardware) And if there’s a code issue, it’ll be a LOGIC issue so quoting one line of code won’t show it - you’ll need to show how your processing things much wider than this one write statement.

Plus I still think there’s value in testing a scenario with your hardware. Have an app that just sends ++addr\r on a button press (surely you have a button on the G30 you can use? if not, can you wire up a GPIO?) and capture the trace on the scope then.

Yeah, @Brett has a point.

You supplied your Serial Port handling class. But of course it doesn’t live on its own. Maybe an entire program, as simple as possible, and that causes the error would be a more efficient post to get help faster.

For instance I had no idea the “unresponsiveness” of the PIC was about the GPIB side until you got explicit about that element. I assumed it was one of either no PIC TX traffic or GetLine() always returning null on G30. Do you even call GetLine() ? Probably, but we can’t see that.

What about ++addr\r\n

I didn’t want to get into the GPIB part right off the bat because it is hard for me to explain it all at once in detail.

Yes I call Getline() and it works. I can read the address from the PIC or the version with ++ver and it works but I think the G30 is doing something which causes the PIC to focus its attention solely on the serial communication. I will post the simple test program I have been using.

@Justin Yes I tried \r\n initially, it gives the same behavior as \r. I am switching to \r since I was told \r\n can vary across operating systems.

@jwizard93 CR is equivalent to \r in everything as far as I am aware.

Ok here is my code…go easy on me now.

Main Program:

using System;
using Microsoft.SPOT;
using System.Threading;

namespace MFConsoleApplication2
{
public class Program
{

    public static void Main()
    {
        try
        {
            MySerialUSBDevice GPIB = new MySerialUSBDevice("COM2", 57600, System.IO.Ports.Parity.None, 8, System.IO.Ports.StopBits.One, "\r\n");
            Thread.Sleep(50);
            GPIB.SendLine("++addr"); //should respond with 20 by default GPIB address
            Thread.Sleep(50);

            for (; ; )
            {

                string line = GPIB.GetLine();
                Thread.Sleep(50);

                if (line != null)
                {

                    Debug.Print(line);

                }

            }
        }
        catch (Exception ex)
        { Debug.Print(ex.ToString()); }
    }
}
}

Serial Device Class:

using System;
using System.Text;
using System.IO.Ports;
using Microsoft.SPOT;


public class MySerialDevice
 {
protected SerialPort commport = null;
protected string commerr;
protected string inbuffer;  //local input buffer
protected string newline;    //newline character or string
protected object buflocker = new object();

public MySerialDevice(string portName, int baudRate, Parity parity, int dataBits, StopBits stopBits, string newline)
{
    inbuffer = "";
    this.newline = newline;
    commport = new SerialPort(portName, baudRate, parity, dataBits, stopBits);
    commport.DataReceived += new SerialDataReceivedEventHandler(DataReceivedHandler);
    commport.Open();


}

private void DataReceivedHandler(object sender, SerialDataReceivedEventArgs e)
{
    const int BUFFER_SIZE = 128;
    byte[] buffer = new byte[BUFFER_SIZE];
    int amount = commport.Read(buffer, 0, BUFFER_SIZE);

    if (amount > 0)
    {
        char[] characters = Encoding.UTF8.GetChars(buffer);
        string received = new string(characters);
        //  string received = BitConverter.ToString(buffer, 0, buffer.Length);
        lock (buflocker)
        {
            inbuffer += received;
            Debug.Print(received);
        }
    }
}
public void SendLine(string outstr)
{
    try
    {
        string message = outstr + "\r";
        byte[] test = Encoding.UTF8.GetBytes(message);
        Debug.Print(test.ToString()); //testing coversion is correct
        commport.Write(Encoding.UTF8.GetBytes(message), 0, message.Length);
    }
    catch (Exception ex)
    { commerr = ex.Message; }
}
public string GetLine()  //return last line received or null
{
    int pos = -1;
    string buffercopy;
    if (inbuffer != null)
    {
        buffercopy = inbuffer; //no need to lock when copying a reference (atomic operation) 
    }
    else
    { buffercopy = ""; }

    if (buffercopy.Length > 0) { pos = buffercopy.IndexOf(newline); }
    if (pos >= 0)
    {
        lock (buflocker)
        {
            //here inbuffer may have changed and be different from buffercopy but pos is still valid (new characters appended at the end)
            string line = inbuffer.Substring(0, pos);  //line without terminating string/char                        
            StringBuilder tmp = new StringBuilder(inbuffer);
            tmp.Remove(0, pos + newline.Length);  //remove line+term. string/char
            inbuffer = tmp.ToString();  //save as new buffer
            return line;
        }
    }
    else
        return null;
}
 }

Ok the exact problem has been replicated by adding a very weak capacitor between the TX and RX lines of the PIC on my friend’s fully working set up (which did not have a G30 involved). With the capacitor added, everything worked until he did a ++command then it failed just like mine. He removed the capacitor and it stopped, thus proving that the wires used to go from the G30 development board to the PIC are creating cross talk. If I ever get this PCB working I’ll know for sure (I accidentally screwed up a footprint pretty bad, I mirrored what it was supposed to be because I think I added it from the wrong view of the board.

Been there. :sweat: I’m sorry you have that problem. If that component has dip pins don’t forget you can proto by just bending them all the way around.

Yeah I mean in one of your scope images it is clear that the PIC’s TX traffic causes some issue on the PIC’s RX. A small ripple is clearly depicted. Seems totally plausible that some bit flip errors would be caused by parasitic capacitance between the lines.

@jwizard93 I was able to bend the component’s pins (SMD l6470) and replaced the components that were shorted from the error (took out my G30). I just made a separate post for troubleshooting my PCB if you would like to add some input (: trying to get the G30 to register in FEZ Config but no luck, my computer does make a DING when a plug it in though.