Sorry for not giving any updates or anything for so long. I'm still working on this little by little. It's been hard to find time lately as I just bought a house and am trying to finish getting settled in. Hasn't left much time for fun stuff.
Sorry for not giving any updates or anything for so long. I'm still working on this little by little. It's been hard to find time lately as I just bought a house and am trying to finish getting settled in. Hasn't left much time for fun stuff.
Hello Bill,
What a great DRO project you have done.
I think I want to give this a try. I found this thread after I have bought a 18F87J50 demo board, this PIC has USB capabilities. Boy does that add complexity!
I only want a single DRO in my own VB program so I can just buy a $15 Serial to USB adapter and try your much simpler method.
I just built a hex file from your code using MPLAB IDE v8.01 and I ended up with a byte for byte copy of your hex file, that was cool.
I think I'll order some 12F675's tonight.
Would you care to share some VB code that reads the serial port and puts the scales value in a text box?
Thanks,
Dale
Hi Dale,
My program is a torturous mess of VB5 object code, so you probably wouldn't want to copy it
The PIC code responds to 2 byte commands with a VB friendly string (I think it is all documented in the source listings). The receiving app' has to asynchronously workout what it has received then act appropriately (sound hard than it is) . I'll dig out some code for you later.
Bill
Bill
Dale,
This is how it's done in my application ATM (I'll try to simplify it later)
Data received by the Comm control is passed to a Scale Control object in the form of a string.
Code:Private Sub MSComm_OnComm() Dim s As String 'Dim T As Single Select Case MSComm.CommEvent Case comEvReceive s = MSComm.Input SC.DataInput s 'pass data to scale control object Case Is = comEvCTS 'CTS line change If MSComm.CTSHolding Then SendIdentify Else SC.RemoveAll 'lead unplugged End If End Select End Sub
The Scale Control object splits up the string, works out what to do with the parts and passes that data onto the appropriate handler.
The Vernier Scale object has to work out the data type convert it and save it in a standard form (e.g. inches)Code:'* < DataInput Sub Header > '* Author.......: {UserName} '* Date.........: 03-Aug-2007 12:32 '* Purpose......: Data from verniers '* Assumptions..: '* Effects......: '* Inputs.......: sting data from scales '* Returns......: '* ------------------------------------------------------------------------ Public Sub DataInput(vData As String) Dim strErrmsg As String If Not IsInIDE() Then On Error GoTo DataInputError '------------------------------------------------------------------------ Main Code 'update appropriate vernier class Dim VS As clsVernier 'Vernier scale object Static RXS As String Dim SCid As String Dim sData As String Dim vMode As Integer Dim vType As String Dim vUnit As String RXS = RXS & vData Do While InStr(RXS, ":") 'Len(RXS) >= 9 sData = Sfmt.SplitAtDelim(RXS, ":") Select Case Left(sData, 1) Case Is = "C" 'connect e.g CX SCid = Mid(sData, 2, 1) 'AddScale ScID RaiseEvent ScaleComms("I0") Case Is = "D" 'disconnected e.g DX SCid = Mid(sData, 2, 1) RemoveScale SCid Case Is = "I" 'info string ID,Mode,Type,Unit e.g. IX,0,Decimal,Inch: SCid = Mid(Sfmt.SplitAtDelim(sData, ","), 2, 1) vMode = Sfmt.SplitAtDelim(sData, ",") vType = Sfmt.SplitAtDelim(sData, ",") vUnit = sData If Not Scales.Exists(SCid) Then AddScale SCid For Each VS In Scales ' find the correct Vernier Scale object If VS.Key = SCid Then VS.Mode = vMode VS.ScaleType = vType VS.Unit = vUnit End If Next Case Is = "R" 'scale has been zeRoed (can't use Z) SCid = Mid(sData, 2, 1) For Each VS In Scales If VS.Key = SCid Then VS.ResetAbsolute End If Next Case Else 'data e.g. X+00.0000 SCid = Left(sData, 1) 'uses the the identifier e.g. W, X,Y or Z to choose the scale ID If Scales.Exists(SCid) Then 'check if scale ID is in scales collection Set VS = Scales.Item(SCid) ' set current vernier scale object VS.Setdata Right(sData, Len(sData) - 1) ' pass data End If End Select Loop '------------------------------------------------------------------------ End of Main Code
The PIC can output three type depending the make of digital vernier used:
1)A 6 digit Hex number where 20480(d) units = one inch
2)A signed two significant digit + four decimal place string in Inches
3) A signed three significant digit + two dp string in millimetres.
In order to improve the display stability and remove jitter and glitches I added a simple filter to the output.Code:Public Sub Setdata(sData As String) 'takes sData string e.g. H000000 (hex 1/20480"), +00.0000 (inches) or -000.00 (mm) 'and converts it to ABS value Dim pos As Long Dim NV As Single Select Case True Case Mid(sData, 5, 1) = "." 'decimal vernier in metric mode NV = Val(Right(sData, 7)) / 25.4 Case Mid(sData, 4, 1) = "." 'decimal vernier in inch mode NV = Val(Right(sData, 8)) ' convert decimal string Case Left$(sData, 1) = "H" ' convert hex string pos = 1 - Val("&" & sData & "00") 'shift 24bit to 32bit and invert NV = pos / 5242880 '20480* 256 End Select 'add to glitch filter If mRev Then AddToFilter NV * -1 Else AddToFilter NV End If mController.Refresh Me 'update the controller End Sub
The display routine reads the Scale object's AbsValueInch or AbsValueMM (the scale object does the conversion to a single precision variable).Code:Private Sub AddToFilter(NV As Single) 'filter new value add to abs value Static FI As Integer 'filter index Dim n As Integer Dim FT As Integer FT = UBound(Filter()) Dim Tot As Single 'glitch filter 'average last few readings Filter(FI) = NV FI = FI + 1 If FI >= FT Then FI = 0 For n = 0 To FT - 1 Tot = Tot + Filter(n) Next mvarAbsValueInch = Tot / FT End Sub
Bill
Bill
Thanks, thats great, I'm sure I can make use if this.
I'm still considering using an 18F13K50 20 pin USB PIC but I did order the 12F675's.
I'm wading thru the Microchip USB dll, mpusbapi.dll. It might be not too bad and I can still adapt your VB code somewhat to do it.
I'm thinking of making a round PCB the size of a 2032 battery that is used in my calipers. One SOIP 18F13K50 and very few external components. It will have a vertical mini-USB connector that comes thru a hole in the battery lid. I can sneak the 2 signal wires inside the case to their pcb pads and solder them on thru the existing connector hole. Should be pretty neat, especially if I can use the USB PIC.
24 inch calipers for $80 and DRO to a PC, very appealing.
Dale
Be aware that the callipers have the battery +ve grounded (i.e. they sort of run a negative rail).
I was considering making an opto-isolated version to avoid the problem in future.
Bill
I don't think mine has a +ve Gnd.
When I check for continuity, with the battery out, between both battery contact points on the pcb and the metal of the caliper, they are both open.
That sounds like a very different (and better) type of calliper. The 2032 battery is a great improvement. What type of calliper is it? Are you sure that it outputs the same code as the cheaper Chinese ones?
Bill
Yes they are Chinese output, confirmed with my 100mhz digital USB storage scope, although I have yet to translate the data stream.
I have both an 18 inch and a 24 inch and I got them on Ebay recently from seller 800watt.
These are big an heavy calipers, well worth the money, even though they are inexpensive.
By the way I checked my cheap Habor Freight 4 and 6 inch calipers and they are +ve gnd.
Great. Keep us informed on your progress and let me know if I can help with modifying the PIC code.Yes they are Chinese output, confirmed with my 100mhz digital USB storage scope, although I have yet to translate the data stream.
He's got some nice bits there. (It's a pity it's so expensive to ship heavy goods over to the UK)...from seller 800watt.
Bill
Bill,
I am stuck because I can't access the dll from vb6, I know that the answer is simple:
Here is the VB6 code I am testing:
Here is what I believe is the C code from the source files for mpusbapi.dll:PHP Code:
Public Declare Function MPUSBGetDeviceCount Lib "mpusbapi.dll" Alias "_MPUSBGetDeviceCount" (ByVal pVID_PID As String) As Long
Global count As Long
Sub OpenMPUSBDevice()
count = MPUSBGetDeviceCount("vid_04d8&pid_003f" & Null) ''ERROR here with Error 49 Bad DLL calling convention
End Sub
The DLL routine returns a DWORD which I think is VB6 Long and the argument is PCHAR which I think is a Null terminated string so I added the Null in calling it.PHP Code:
DWORD MPUSBGetDeviceCount(PCHAR pVID_PID)
{
DWORD count; // Number of USB device with matching VID & PID
count = 0; // Initialization
for(int i = 0; i < MAX_NUM_MPUSB_DEV; i++)
{
if(MPUSBGetDeviceLink(i,pVID_PID,NULL,NULL,NULL) == MPUSB_SUCCESS)
count++;
}//end for
return count;
}//end MPUSBGetDeviceCount
I've tried it many different ways with no luck-- always ' Error 49 Bad DLL calling convention'.
Have you got any thoughts on this?
I have attached the Dll if you want to quickly try this.
Thanks,
Dale
Do a google code search for mpusbapi lang:basic and you will find an example of basic program using this function
page link it gives is no longer valid but all the code is there.
http://google.com/codesearch?q=mpusb...%3Abasic&hl=en
George
Thanks George, never seen that code search before, very useful.
I have already seen that code, it is coded for VB.net (or whatever Microsoft named VB6 successor). Not compatible with VB6, they shouldn't even have had the right to call it VB in my opinion, code is not very convertible.
I copied the code it used to declare and call MPUSBGetDeviceCount and it got the same error, I went digging and found the C code in the dll and tried to fix the problem with the Null and Long.
Dale
If memory serves, the ByVal statement should pass a null terminated string to the dll so you shouldn't need to add the termination.
A quick google threw up others having the same problem with the microchip dll (suggesting that it doesn't use standard calling conventions - i.e. not VB compatible)
Might be worth chasing Microchip ???
Bill
Bill,
Didn't work without Null either, good to know Byval sends it.
I already have a Microchip ticket open on this but haven't had a response yet.
I hope I can use VB6. I never went to VB.net, it was just too different and a money grab. Someday I'll just learn C.
Thanks,
Dale
Snap !I hope I can use VB6. I never went to VB.net, it was just too different and a money grab. Someday I'll just learn C.
I tried VB.net as a beta - it was like starting all over again, NOTHING worked !
A friend suggest C# but ... I think my programming days are over (or at least the days of learning a new language are) , I don't get anything out of it any more
Bill
Bill,
Well that was interesting, I can now send and receive data to the 18F87J50 demo board with a simple VB6 program.
The template like code was generated by EasyHID and it uses mcHID.dll.
I just set the VendorID, ProductID, BufferInSize, BufferOutSize.
Then I wrote a little code to toggle the LEDs (on the pic board) every time there is a state change of a switch on the pic board. Read and write accomplished.
Attached is the VB6 project and the dll if anyone wants to 'look' at it.
To run it you need PIC18F87J50 FS USB PIM demo board with 'USB Device - HID - Simple Custom Demo - C18 - PIC18F87J50 PIM.hex' loaded
Now I just have to mesh your 12F675 asm code into the C++ workspace that Microchip uses for the USB pic's. I hope that is not too hard.
:cheers:
Cheers
Dale
Bill,
Well I now am able to modify the C code, build, load and run a hex file. I spent a lot of time trying to consolidate all the necessary .c and .h files into the project directory but eventually gave up. In all there are about 16 files loaded or included, wow.
Anyway, I can very easily call an asm function from C or insert asm code inline in C (with a little syntax changing). So I am ready to dive in.
First, I am not sure how not having a +ve gnd on the caliper changes the input signal components. I don't think it does. Would I just use the LED/3.3k components you used?
In your code below it says you are setting the reference voltage to 0.75v but I can't figure out how that is. The B'10100011' sets VRR to low range and VR3:VR0 to 0011 or decimal 3. Doesn't that make the ref voltage = (3/24)*5 = 0.625? I'm not tying to be picky, I just want to be sure that I understand assembly/binary/.... because I am so rusty at it.
Anyway, wish me luck!!
Dale
Code:;initialise comparator etc ; VInit BSF status,RP0 ;select bank 1 movlw B'10100011' ;set Vref ~ 0.75v, Vdd = 5v;(24/5)* 0.75 movwf VRCON
Hi Dale, your progress is impressive
I'll check the ref value code tomorrow. However, your scale works at 3v from the 2032 cell, so you'll want to set the comparetor threshold higher any way. Similarly, you may need to use 3v zeners (or perhaps green leds) to limit the voltage out of the pic (if the pic runs at 3v, not 5v, you could dispence with the doiodes altogether)
Bill
Yep, I wish I had a 3V signal level, then I would just have TTL input levels and use digital I/O ports on the Pic.
Not to be, even though the battery is 3v, the output signal is only 1.5v.
One of the main things I need to do is get rid of the battery and get the 10 microamps I need to power the caliper form the USB. I was just going to use a 3V zener to power it with a 100 uF cap on it.
I will run the Pic on 5v from the USB.
Now this is a stupid question, why can't I just put the data lines to the comparator thru 10k resistors and forget the diodes?
Thanks,
Dale
P.S. I spoke too soon on how easy it was to add asm to C18. When I actually try it I get syntax error at _asm. Supposedly you just put ams between _asm and _endasm, oh well, more grief (3 hours so far on this one). The more I look at the C code the more I might try just doing it.