Custom software for RV1S/RV4S

Started by arvydas, August 20, 2015, 12:33:35 PM

Previous topic - Next topic

Jason

Quote from: arvydas on August 24, 2015, 01:36:14 PM
When you click on the user controls for the machine to move by 1 to the right, the data sequence looks like this:

yeah, remember that moving involves moving both cylindrical axis motors AND
rotating the head to maintain orientation of the part.
I suspect that each base address corresponds to one DSP.
302 being the X, 300 and 301 being Y and rotate (both with no movement in your test, so
no way to tell yet) and 303 being the Z which you never tested.

The commands are going to be speed, direction and number of steps. I think I did start
disassembling the calling functions which made it fairly clear but it was a while ago and I
just moved on.

With your hooking, I won't bother trying to capture any more, I'll concentrate on the
interfacing.
Do you have a way of generating compatible .dll functions? I assumed that GCC or
M$ C++ wouldn't be decorate the C++ the same as the Borland stuff.


Mike

Can't say I've looked close enough to notice, but does it actually make any attempt to keep the theta axis square when moving ? I can't see any reason to do this -  all it needs to know is the delta between the start and end position (and ideally should get to the latter by the time it's at the end position, but without moving so fast the part slips).

If it is as simple as steps/direction/speed to each DSP, I wonder if instead of interfacing to the ISA card, it might be almost as easy to ditch the DSP card completely and just feed the trapped calls via USB into an MCU or small FPGA.
One nice thing about pick & place versus CNC is it's basically moving from one place to an other, and you don't really care about accurate speeds or co-ordination between axes.






 

arvydas

I've been using IDA Pro and custom script I wrote to get the information without hooking as this was the fastest method. Seems that 303 is rotation address.

Attached debug log when rotating by 900. All numbers in hex.

OUT 303, 80
OUT 303, 40
OUT 303, 0
OUT 303, 20
OUT 303, 10
OUT 303, 0
OUT 303, 8a
OUT 303, 40
OUT 303, 0
OUT 303, 20
OUT 303, 10
OUT 303, 0
OUT 303, 84
OUT 303, 40
OUT 303, 0
OUT 303, 81
OUT 303, 4f
OUT 303, 0
OUT 303, 84
OUT 303, 40
OUT 303, 0
OUT 303, 89
OUT 303, 47
OUT 303, 0
OUT 303, 82
OUT 303, 40
OUT 303, 0
OUT 303, 83
OUT 303, 4d
OUT 303, 0
OUT 303, 84
OUT 303, 40
OUT 303, 0
OUT 303, 8a
OUT 303, 40
OUT 303, 0
OUT 303, 84
OUT 303, 46
OUT 303, 0
OUT 303, 80
OUT 303, 40
OUT 303, 0
OUT 303, 20
OUT 303, 10
OUT 303, 0
OUT 303, 81
OUT 303, 44
OUT 303, 0

IDA Pro is capable to generate readable reverse engineered pseudo code for all functions.

I've hit a road block with generating a proxy DLL. Win98 does not want to load rvplace.exe and it complains that it can't find the exported functions even though dumpbin shows them correctly. The proxy DLL loads just fine with rvplace.exe on Win XP and up. Tried to compile the DLL with VC6 and MSVS2005 on Win98, XP and 7, but I end up getting the same error message.

I'm using genwrapper which you can find here: https://github.com/floodyberry/genwrapper and you can find more details about the implementation here: https://floodyberry.wordpress.com/2008/09/08/generating-dll-wrappers/

However, it generates incorrect def file that needs fixing in order to compile. LMK if any of you would be interested to have a look at the implementation and I'll upload the source code I currently have. My first step was to generate a basic DLL that forwards all functions and gets loaded by rvplace.

My next step to solve this is to inject a DLL in to rvplace.exe process and hook functions dynamically. This way I should be able to hook any function within rvplace.exe and any library it loads without the need to create a proxy DLL. This is somewhat a challenge as hooking functions in Win 98 is very different than hooking on NT based Win version with CreateRemoteThread, however I'm sure I will be able to solve it. Just need to get the basic Hello World thing going with injector and injectable DLL :-)


Mike

That looks like it's shifting nibbles of data at a time . If you read the right-hand digits vertically they are always in pairs.
Top 4 bits are probably commands, with the bottom 4 as parameters : 
Bit 7 :  write MSnibble
Bit 6  : write LSnibble




WillReeve

I wonder if something from these guys would fit the bill:

http://www.planet-cnc.com/index.php?page=home

should interface straight into the stepper drivers?

Jason

Phonoplug, did you manage to contact the software guy?

sarason

Hows this negotiation working out ?

sarason

alanambrose

>>> That looks like it's shifting nibbles of data at a time

Ah v good, I just twigged yesterday that the card is an 8-bit ISA card - so that makes sense. Also, I just noticed this:

http://anagram.net/nuts/Versatronics/Contents%20of%20ramp%20dot%20sys.png

Alan

alanambrose

>>> I've hit a road block with generating a proxy DLL. Win98 does not want to load rvplace.exe and it complains that it can't find the exported functions even though dumpbin shows them correctly. The proxy DLL loads just fine with rvplace.exe on Win XP and up. Tried to compile the DLL with VC6 and MSVS2005 on Win98, XP and 7, but I end up getting the same error message.

I know this is an old thread, but I see the apps were originally compiled with Borland 5.02. There's one class in stepDsp.dll (exports below) - so it was probably at least part caused by Borland C++ name mangling vs. Msft mangling.

A.

LIBRARY     STEPDSP.DLL

EXPORTS
    @Stepdsp@$bctr$qipcp6Speeds    @14  ; Stepdsp::Stepdsp(int,char*,Speeds*)
    @Stepdsp@$bdtr$qv              @16  ; Stepdsp::~Stepdsp()
    @Stepdsp@CalcMoveTime$quii     @2   ; Stepdsp::CalcMoveTime(unsigned int,int)
    @Stepdsp@CalcProcTime$qui      @12  ; Stepdsp::CalcProcTime(unsigned int)
    @Stepdsp@CalcRampTime$qui      @11  ; Stepdsp::CalcRampTime(unsigned int)
    @Stepdsp@CalcSpeedTime$quii    @13  ; Stepdsp::CalcSpeedTime(unsigned int,int)
    @Stepdsp@CalculateRamp$qui     @3   ; Stepdsp::CalculateRamp(unsigned int)
    @Stepdsp@GearAxis$qii          @10  ; Stepdsp::GearAxis(int,int)
    @Stepdsp@GetByte$qi            @45  ; Stepdsp::GetByte(int)
    @Stepdsp@GetErrorStatus$qi     @26  ; Stepdsp::GetErrorStatus(int)
    @Stepdsp@GetMoveStatus$qi      @47  ; Stepdsp::GetMoveStatus(int)
    @Stepdsp@GetPos$qi             @21  ; Stepdsp::GetPos(int)
    @Stepdsp@GetResetStatus$qv     @35  ; Stepdsp::GetResetStatus()
    @Stepdsp@GetStatus$qi          @25  ; Stepdsp::GetStatus(int)
    @Stepdsp@Init$qv               @18  ; Stepdsp::Init()
    @Stepdsp@InitAxis$qi           @19  ; Stepdsp::InitAxis(int)
    @Stepdsp@InitXY$qlluiii        @28  ; Stepdsp::InitXY(long,long,unsigned int,int,int)
    @Stepdsp@LoadCode$qv           @17  ; Stepdsp::LoadCode()
    @Stepdsp@LoadRamp$qv           @15  ; Stepdsp::LoadRamp()
    @Stepdsp@ModifySpeed$qii       @8   ; Stepdsp::ModifySpeed(int,int)
    @Stepdsp@MotorOff$qi           @23  ; Stepdsp::MotorOff(int)
    @Stepdsp@MoveAxis$qiluii       @31  ; Stepdsp::MoveAxis(int,long,unsigned int,int)
    @Stepdsp@MoveAxis1$qiluii      @5   ; Stepdsp::MoveAxis1(int,long,unsigned int,int)
    @Stepdsp@MoveAxisRel$qiluii    @32  ; Stepdsp::MoveAxisRel(int,long,unsigned int,int)
    @Stepdsp@MoveAxisRel1$qiluii   @6   ; Stepdsp::MoveAxisRel1(int,long,unsigned int,int)
    @Stepdsp@MoveXY$qlluii         @29  ; Stepdsp::MoveXY(long,long,unsigned int,int)
    @Stepdsp@MoveXY1$qlluii        @1   ; Stepdsp::MoveXY1(long,long,unsigned int,int)
    @Stepdsp@OutPort$qiuc          @50  ; Stepdsp::OutPort(int,unsigned char)
    @Stepdsp@Read$qi               @42  ; Stepdsp::Read(int)
    @Stepdsp@ReadAck1$qi           @43  ; Stepdsp::ReadAck1(int)
    @Stepdsp@ReadAck2$qi           @44  ; Stepdsp::ReadAck2(int)
    @Stepdsp@ReadPort$qi           @51  ; Stepdsp::ReadPort(int)
    @Stepdsp@ResetCard$qv          @27  ; Stepdsp::ResetCard()
    @Stepdsp@RingBack$qiuc         @33  ; Stepdsp::RingBack(int,unsigned char)
    @Stepdsp@RingBackOut$qiiuc     @34  ; Stepdsp::RingBackOut(int,int,unsigned char)
    @Stepdsp@SendByte$qiuc         @39  ; Stepdsp::SendByte(int,unsigned char)
    @Stepdsp@SendMaster$qiuiiuiuii @4   ; Stepdsp::SendMaster(int,unsigned int,int,unsigned int,unsigned int,int)
    @Stepdsp@SendSlave$qiii        @7   ; Stepdsp::SendSlave(int,int,int)
    @Stepdsp@SetBreakPoint$qii     @9   ; Stepdsp::SetBreakPoint(int,int)
    @Stepdsp@SetDirection$qii      @22  ; Stepdsp::SetDirection(int,int)
    @Stepdsp@SetPos$qil            @20  ; Stepdsp::SetPos(int,long)
    @Stepdsp@SetResetStatus$qv     @36  ; Stepdsp::SetResetStatus()
    @Stepdsp@SetStatus$qii         @24  ; Stepdsp::SetStatus(int,int)
    @Stepdsp@StartXY$qv            @30  ; Stepdsp::StartXY()
    @Stepdsp@WaitBP$qi             @49  ; Stepdsp::WaitBP(int)
    @Stepdsp@WaitNotBusy$qi        @38  ; Stepdsp::WaitNotBusy(int)
    @Stepdsp@WaitNotSame$qiuc      @46  ; Stepdsp::WaitNotSame(int,unsigned char)
    @Stepdsp@WaitSame$qiuc         @48  ; Stepdsp::WaitSame(int,unsigned char)
    @Stepdsp@Write$qiuc            @37  ; Stepdsp::Write(int,unsigned char)
    @Stepdsp@WriteAck1$qi          @40  ; Stepdsp::WriteAck1(int)
    @Stepdsp@WriteAck2$qi          @41  ; Stepdsp::WriteAck2(int)

dirk1980

Hello,
has something come out here after 5 years?

I like the software and hardware of the RV4s quite well and I would like to use them for years to come.
But as I get more and more hardware problems I am looking for an alternative in parallel.
I would prefer to only replace the hardware, but if necessary, I also change everything.

If someone needs help to get ahead, that's not a problem.
I would like to use my machine for a long time!

I know openPNP with GRBL motor drivers.
Logically, you can't just exchange them.
But maybe there is something already in that direction?
Has anyone done anything with it?

Gopher

Quote from: dirk1980 on July 20, 2020, 04:58:06 PM
Hello,
has something come out here after 5 years?

I like the software and hardware of the RV4s quite well and I would like to use them for years to come.
But as I get more and more hardware problems I am looking for an alternative in parallel.
I would prefer to only replace the hardware, but if necessary, I also change everything.

If someone needs help to get ahead, that's not a problem.
I would like to use my machine for a long time!



I know openPNP with GRBL motor drivers.
Logically, you can't just exchange them.
But maybe there is something already in that direction?
Has anyone done anything with it?

If your hardware dies, it seems pretty likely the future is full of those Chinese P&Ps, in many ways the vision equipped ones are better than an RV but the software seems to be pretty horrid and makes you walk through even more hoops than Versatronics does. However there are already considerably more of them out there than there are RVs and there do seem to be whispers of OpenPnP efforts on some of those, many hands make light work and all that - plus the chinese software might catch up.

Moving your data out of an RV isn't really a huge issue. Pretty much all machines basically take the same XYR data you probably started with (or you can extract it from the TFR file) and store it in fairly simple formats. The only things you have to recreate from scratch are package definitions.

dirk1980

Some of the Chinese P & Ps may not be bad, but I want something that you can fix yourself.
I think most of the problems come from the old PC, ISA are dying out and Win98 has long been outdated.
And if a solution has been found here in the meantime, that would be great.

If I knew what happened in the individual modules and how they work together, I could perhaps help to replace parts.

What does the head/arm controller do? 12 & 9V, relay control and ?
Does anyone have information about the protokoll?

The hardware in the feeders is quite simple and can easily be updated on something new.
The connection of alternate feeders should also not be a problem.


Other software and controls would be an alternative.
But nothing that can be easily exchanged, except the PCB data.

Jason

I got armtest.exe and rvplace.exe controlling RV hardware Windows 10 64-bit
via my USB to ISA adapter.
rvplace will perform the initial homing and then perform the warmup  8)

However, I now have to do something about image grabbing.
Would anyone happen to have archived pxc_15.exe from the Imagenation
support site? This was a Win64 release of drivers according to this:

https://web.archive.org/web/20150612101854/http://www.imagenation.com/dnpages/pxc_files.html




Jason

I tried them a few years ago and I got a very bland reply back stating the card is obsolete.... useful eh?

Regardless, I have made progress.

I have compiled my own substitute versions of PXC2_95.dll and Frame_95.dll and managed to get RVPlace to link with them.
I needed to apply liberal amounts of IDA Pro and Ghidra to figure out exactly how RVplace links with them.
I popped some logging in each function and discovered the application only calls a small portion of the Imagenation API (see logs below)

I now have RVplace opening the demo job and placing it on Windows 10 64bit.
It obviously fails all the visioning checks because at the moment every frame/row returned to RVplace is full of black pixels.
Next job is to open a Windows capture device (Directshow API) and present real frames from that instead of blank ones.
I try it with one of the cheap USB  "EasyCap" composite video devices to start with. I'm not sure whether to expect any
aspect ratio issues (square vs non-square pixels etc).


Here are the logs from my substitue dlls as it made 3 attempts to vision the first component from the demo job:

DllMain : Process attach
PXC_OpenLibrary : iface=0x33b99ee ,size=0x138
AllocateFG
SetWidth : w=768
SetHeight : h=576
SetLeft : l=4
SetTop : t=0
SetXResolution : rez=768
SetYResolution : rez=576
AllocateBuffer : dx=768 dy=576 type=0x8
SetCamera : port=0 flags=0x0
Grab : flags=0x0
Grab : flags=0x0
SetCamera : port=0 flags=0x0
Grab : flags=0x0
Grab : flags=0x0
SetCamera : port=0 flags=0x0
Grab : flags=0x0
SetCamera : port=0 flags=0x0
Grab : flags=0x0
SetCamera : port=0 flags=0x0
Grab : flags=0x0
FreeFG
DllMain : Process detatch


DllMain : Process attach
FRAMELIB_OpenLibrary : iface=0x33b9b26 ,size=0x68
GetRow
GetRow
......
GetRow
GetRow
GetRow
FreeFrame
FRAMELIB_CloseLibrary
DllMain : Process detatch