Transmitting the screen content over ansi terminal is working, but some issues...
First, have to change default initial columns and rows in the terminal window, or it gets all messed up.
Setting cols to 128 and rows to 50 makes it work.
Second, it is slow to update and have to add in extra delays to keep terminal from getting jumbled.
So, unless can improve things, will need to make another screen buffer for serial transmit and use a cog for serial terminal interaction...
Here's the current code to send VGA screen buffer out to ansi terminal.
Need to improve color handling a bit...
Maybe need to request something from terminal, like "Device Status Report", as a way to make sure ready for more data...
typedef struct Ansi4 {
char fgcolor;
char bgcolor;
char curchar;
char cureff;
} Ansi4;
void TransmitScreen()
{
Ansi4* pChar = vga.GetBuffer();
Ansi4* pLastChar = pChar;
printf("\x1B[?25l"); //hide cursor
for (int y = 0; y < rows; y++)
{
//printf("\x1B[C2J"); //clear screen
char fgcolor = pChar->fgcolor;
char bgcolor = pChar->bgcolor;
printf("\x1B[38;5;%dm", fgcolor); //Set foreground color
printf("\x1B[48;5;%dm", bgcolor); //Set background color
printf("\x1B[%d;%dH", y+1, 1); //Set to this row, first column
//_waitus(10);
for (int x = 0; x < cols; x++)
{
//printf("%c", pChar->curchar);
putchar(pChar->curchar);
//buf[x] = pChar->curchar;
pChar += 1;
}
//printf("\n");
_waitms(1);
}
}
This binary now displays the VGA screen info on ANSI terminal over USB serial connection.
Had to use a cog to do this because ANSI screen updating is slow.
Not sure how to improve this... It seems the terminal has trouble keeping up without a bunch of delays added...
Could increase baud rate to 2M, but not clear that would help...
Anyway, this seems to at least allow one to see what is going on terminal window.
Note: One must override the default terminal size like shown in attached screenshot to get a stable display...
One can interact with USB mouse over terminal, but it's painful with the slow screen updates...
Ladder logic. From the 1970s before we had computers.
Here's what happens (above):
Somebody has hit the latching e-stop button. Operator comes back from lunch to find that the machine won't start. Goes to tell supervisor. Supervisor says he'll have maintenance come over when they are free because they know how to read that screen with all the lines running across it.
Meanwhile, a modern controller displays a message "Motor Cannot Start Until E-Stop Button is Reset. Please Check For Personnel Working on Machine"
Displays were expensive back then is all. The way it works is the display itself is programmed with the messages, and it has master access into PLC memory, then the logic states of the PLC trigger the messages. Protocols like Modbus are built around this model.
Trying to get actual PLC run mode going. Probably should look at ldmicro generated C code to see how, but trying myself first...
Going to try, at the end of every loop:
First, run through program looking for coils, if found, set physical output to match.
Then, run through program looking for contacts, if found, set state to match physical input.
@Rayman said:
First, run through program looking for coils, if found, set physical output to match.
Then, run through program looking for contacts, if found, set state to match physical input.
Anything that works is good enough, but I'd say the typical way is run through the physically existing outputs writing out the logical state then run through the physically existing inputs reading in those logical states. What the Ladder Logic uses isn't factored into the I/O scan.
Might have it going in run mode. Was tripped up for a second because inputs were reading high with nothing connected.
Then remembered that they have a tendency to do that...
One question is to let mouse input toggle I/O pin outputs for contacts.
This could be problematic, like if connected to a grounded switch?
Thinking need something like a breadboard to test this out now...
Normally, all simple On/Off I/O is isolated via optocouplers wired for pull-up/down. Whichever you prefer.
Euro wiring is usually pull-down (switched high) aka PNP. US wiring is usually pull-up (switched low) aka NPN. There is also car wiring which is NPN inputs and PNP outputs.
And can allow both PNP and NPN wiring on case by case but this demands a lot of terminals. You will see this done for output modules with clean contact relay outputs. And occasionally input modules using AC optocouplers support this.
So, a test bed for the software could forgo the optocouplers but you'd still want to use the pull-up/down resistors to make the logic work the same.
@Rayman said:
It is interesting that ladder logic is still around...
Read it is so people with no programming experience can figure it out...
I have plenty of programming experience, and I can't figure it out... It seems like they start with normal relay ladder wiring diagrams (like the kind when everything was relays), which are a very intuitive way of presenting circuits as if they were a form of functional programming, but then they add some sequential flow control and subroutines and return statements to it? How can that be comprehensible to mere mortals, or even deterministic? Sounds like a tangled mess of poorly-defined interacting implicit concurrent state machines that will inevitably be full of bugs and race conditions. What am I missing?
It isn't a done thing really, certainly not subroutines. Any good Ladder has none of those. But even with the clutter of lots of in-order chunks of code it is still relatively deterministic simply because those are all non-blocking operations.
PS: There's no such thing as a loop in Ladder. That's the biggest reason why I say the I2C example that JMG posted will be setup for a hardware I2C controller rather than bit-bashing anything.
Not that I2C couldn't be done as bit-bashing behind the scenes. Just the Ladder won't do it.
Think run mode is now working.
Time to implement cycle time...
Looks like the usual cycle time is 10 ms, from ldmicro manual.
This simple one rung ladder takes 0.03 ms to execute but 7 ms to draw.
So, running needs to be in its own cog...
@RossH I'm also liking the idea of using Catalina to compile the Ansi C code that ldmicro creates. Have to look into that sometime.
Thinking that would be more robust and full featured way of running the ladder.
At least, until such a time that this code is fully mature (which may be never...)
Kind of feeling the need for a board with a bunch of switches and pushbuttons and leds to test this thing out...
This is why I've been developing lots of custom P2 Accessory type boards (many are very simple). I mostly use the Eval for starting development and code for individual circuits, then use the Edge Breakout with my custom accessories. From there I got to project PCB.
I'm working on another packaging machine these days. My second big project ever ... When I'm testing the code being developed at the moment I don't just need the real machine, it also needs to be loaded with the packaging consumables and operating at temperature to do the testing. Can't tell if the aligning/synchronising is functioning correctly otherwise. Luckily there is plenty of historical reject rolls of packaging available to run through the machine. Incorrect print, poorly laminated, that sort of thing.
Some parts can be developed independently and then attached as a finished module. I spent a long time getting the steppers operating via Modbus without needing to touch the testing machine.
When the boss is doing his testing he even has to go get customer product to put in the packaging. He's most concerned with pack sealing quality under the various operating conditions.
PS: The most recent work may well all go on the scrap heap. It's far from a certainty for success. It's an experimental add-on for pre-sealing with a second sealing head to improve the seal quality with peanut butter.
@RossH I'm also liking the idea of using Catalina to compile the Ansi C code that ldmicro creates. Have to look into that sometime.
Thinking that would be more robust and full featured way of running the ladder.
At least, until such a time that this code is fully mature (which may be never...)
Before I realized that OpenPLC was (I think - still not 100% sure on this) a command-line utility extracted from LDmicro, I did a quick and dirty port of it to Catalina - just enough to ensure that it could be compiled using Catalina on a PC, and that the resulting binary can then be run on the P2 to generate a C file which can then be compiled on the P2 using Catalina. No warranty expressed or implied!
It only took a few hours, but I stopped work on it when I realized that I really should have started with the LDmicro source code itself - this meant I would essentially have to do the same work over again. I may do this some day, but just in case someone else wants to have a go at it I have attached what I did here - this will give them a clue as to what is required (the .cpp files are the original OpenPLC, the .c files are what I generated from them). The main problem is that OpenPLC is not what is generally known as "clean C" - it is a bit of a mish-mash of C and C++. LDmicro is slightly "cleaner" - I now wish I had started with that.
Comments
Ok, implemented that initial value for simulation and tested by adding an "enable" contact to the simple Start/Stop circuit...
Transmitting the screen content over ansi terminal is working, but some issues...
First, have to change default initial columns and rows in the terminal window, or it gets all messed up.
Setting cols to 128 and rows to 50 makes it work.
Second, it is slow to update and have to add in extra delays to keep terminal from getting jumbled.
So, unless can improve things, will need to make another screen buffer for serial transmit and use a cog for serial terminal interaction...
Here's the current code to send VGA screen buffer out to ansi terminal.
Need to improve color handling a bit...
Maybe need to request something from terminal, like "Device Status Report", as a way to make sure ready for more data...
This binary now displays the VGA screen info on ANSI terminal over USB serial connection.
Had to use a cog to do this because ANSI screen updating is slow.
Not sure how to improve this... It seems the terminal has trouble keeping up without a bunch of delays added...
Could increase baud rate to 2M, but not clear that would help...
Anyway, this seems to at least allow one to see what is going on terminal window.
Note: One must override the default terminal size like shown in attached screenshot to get a stable display...
One can interact with USB mouse over terminal, but it's painful with the slow screen updates...
Works with Putty with all the serial output delays removed.
Still a little slow, but much better...
Ladder logic. From the 1970s before we had computers.
Here's what happens (above):
Somebody has hit the latching e-stop button. Operator comes back from lunch to find that the machine won't start. Goes to tell supervisor. Supervisor says he'll have maintenance come over when they are free because they know how to read that screen with all the lines running across it.
Meanwhile, a modern controller displays a message "Motor Cannot Start Until E-Stop Button is Reset. Please Check For Personnel Working on Machine"
It is interesting that ladder logic is still around...
Read it is so people with no programming experience can figure it out...
However, somebody did add an I2C display element to ldmicro.
Maybe that means you can show that message?
Displays were expensive back then is all. The way it works is the display itself is programmed with the messages, and it has master access into PLC memory, then the logic states of the PLC trigger the messages. Protocols like Modbus are built around this model.
Trying to get actual PLC run mode going. Probably should look at ldmicro generated C code to see how, but trying myself first...
Going to try, at the end of every loop:
First, run through program looking for coils, if found, set physical output to match.
Then, run through program looking for contacts, if found, set state to match physical input.
Anything that works is good enough, but I'd say the typical way is run through the physically existing outputs writing out the logical state then run through the physically existing inputs reading in those logical states. What the Ladder Logic uses isn't factored into the I/O scan.
Might have it going in run mode. Was tripped up for a second because inputs were reading high with nothing connected.
Then remembered that they have a tendency to do that...
One question is to let mouse input toggle I/O pin outputs for contacts.
This could be problematic, like if connected to a grounded switch?
Thinking need something like a breadboard to test this out now...
Normally, all simple On/Off I/O is isolated via optocouplers wired for pull-up/down. Whichever you prefer.
Euro wiring is usually pull-down (switched high) aka PNP. US wiring is usually pull-up (switched low) aka NPN. There is also car wiring which is NPN inputs and PNP outputs.
And can allow both PNP and NPN wiring on case by case but this demands a lot of terminals. You will see this done for output modules with clean contact relay outputs. And occasionally input modules using AC optocouplers support this.
So, a test bed for the software could forgo the optocouplers but you'd still want to use the pull-up/down resistors to make the logic work the same.
I have plenty of programming experience, and I can't figure it out... It seems like they start with normal relay ladder wiring diagrams (like the kind when everything was relays), which are a very intuitive way of presenting circuits as if they were a form of functional programming, but then they add some sequential flow control and subroutines and return statements to it? How can that be comprehensible to mere mortals, or even deterministic? Sounds like a tangled mess of poorly-defined interacting implicit concurrent state machines that will inevitably be full of bugs and race conditions. What am I missing?
It isn't a done thing really, certainly not subroutines. Any good Ladder has none of those. But even with the clutter of lots of in-order chunks of code it is still relatively deterministic simply because those are all non-blocking operations.
PS: There's no such thing as a loop in Ladder. That's the biggest reason why I say the I2C example that JMG posted will be setup for a hardware I2C controller rather than bit-bashing anything.
Not that I2C couldn't be done as bit-bashing behind the scenes. Just the Ladder won't do it.
Think run mode is now working.
Time to implement cycle time...
Looks like the usual cycle time is 10 ms, from ldmicro manual.
This simple one rung ladder takes 0.03 ms to execute but 7 ms to draw.
So, running needs to be in its own cog...
@RossH I'm also liking the idea of using Catalina to compile the Ansi C code that ldmicro creates. Have to look into that sometime.
Thinking that would be more robust and full featured way of running the ladder.
At least, until such a time that this code is fully mature (which may be never...)
Kind of feeling the need for a board with a bunch of switches and pushbuttons and leds to test this thing out...
Doing right now with resistors into headers, but it's not very satisfying...
This is why I've been developing lots of custom P2 Accessory type boards (many are very simple). I mostly use the Eval for starting development and code for individual circuits, then use the Edge Breakout with my custom accessories. From there I got to project PCB.
I'm working on another packaging machine these days. My second big project ever ... When I'm testing the code being developed at the moment I don't just need the real machine, it also needs to be loaded with the packaging consumables and operating at temperature to do the testing. Can't tell if the aligning/synchronising is functioning correctly otherwise. Luckily there is plenty of historical reject rolls of packaging available to run through the machine. Incorrect print, poorly laminated, that sort of thing.
Some parts can be developed independently and then attached as a finished module. I spent a long time getting the steppers operating via Modbus without needing to touch the testing machine.
When the boss is doing his testing he even has to go get customer product to put in the packaging. He's most concerned with pack sealing quality under the various operating conditions.
PS: The most recent work may well all go on the scrap heap. It's far from a certainty for success. It's an experimental add-on for pre-sealing with a second sealing head to improve the seal quality with peanut butter.
Before I realized that OpenPLC was (I think - still not 100% sure on this) a command-line utility extracted from LDmicro, I did a quick and dirty port of it to Catalina - just enough to ensure that it could be compiled using Catalina on a PC, and that the resulting binary can then be run on the P2 to generate a C file which can then be compiled on the P2 using Catalina. No warranty expressed or implied!
It only took a few hours, but I stopped work on it when I realized that I really should have started with the LDmicro source code itself - this meant I would essentially have to do the same work over again. I may do this some day, but just in case someone else wants to have a go at it I have attached what I did here - this will give them a clue as to what is required (the .cpp files are the original OpenPLC, the .c files are what I generated from them). The main problem is that OpenPLC is not what is generally known as "clean C" - it is a bit of a mish-mash of C and C++. LDmicro is slightly "cleaner" - I now wish I had started with that.
Ross.
Digikey is hosting a live online thing about Opta now.
It does seem like P2 could do something similar and better...
https://forum.digikey.com/t/getting-started-with-digikeys-arduino-opta-kit/46079
Arduino is rolling out a new course on how to use opta. Looks to be coming soon....
I like the idea of the trainer too. Looks like Digikey sells a kit with the parts here.
Ok, there's no kit, just a list of individual parts:
https://forum.digikey.com/t/guide-to-selecting-industrial-component-for-education/40833
Also mentions several other small PLCs...
Might have to take a look at the Arduino PLC IDE:
https://www.arduino.cc/pro/software-plc-ide
I think they just said there's some relationship between this and OpenPLC... Guessing it's the same?
The opta has a dual core that they say allows two programs to run simultaneously.
Think P2 could easily run 6 or more programs simultaneously...
Found (or found again) where the OpenPLC programmer says he started from ldmicro:
https://forum.arduino.cc/t/open-source-plc-based-on-arduino/230583/9
Would like to know of ldmicro is compliant with IEC 61131-3
Haven't found anything yet saying it is...
Found the first version of OpenPLC that is based on ldmicro:
https://github.com/thiagoralves/OpenPLC-Ladder-Editor/tree/master/ldmicro-rel2.2
Every time I've come across anything specifically saying it's IEC it also has a licence fee attached. I wouldn't be too concerned about compliance.
Found an interesting PLC training thing:
https://www.learnlab.biz/products/advanced-plc-troubleshooting-training-system
Seems like one could learn the basics of ladder logic with a much simpler setup...
I'm thinking just buttons, switches, and LEDs...
Rule of thumb is view it from the output's needs. Place the output first then think about what is needed for that output to be turned on.
words to live by.