Instrument Control (GPIB, Serial, VISA, IVI)

Showing results for 
Search instead for 
Did you mean: 

Sending and receiving data from PIC18F4550

Go to solution

Ok, i saw some forum discussions about how to make LabView talk with PIC18F4550, and did not find any solution up there, usually all the topics ended with nothing.


Ok, here is what i have done so far:


Microcontroller part: I have downloaded the Microchip Solutions example, compiled the example for PICDEM board, however i did not have PICDEM board, so i just assembled my own simple board with minimal elements. I runned that example on my PIC18F4550 and used the standard Human Interface Device driver, i runned also the example application and could toggle LEDs and read Potentiometer values. Then, once i saw that the device is working, i have uninstalled the driver and disconnected my device from USB.


Now: I have found the manual on the NI website, which says how to generate driver using NI-VISA tool, i have gone through that, and successfully generated driver for my device, then i installed this driver, plugged my USB with PIC, and could see its properties etc.



So far seems ok. Now, seems like a last step, i want to read data lets say from potentiometer through the PIC.

According to the previous manual, i am running now VISA Interactive Control tool, what im going to do now is to send some requests to my PIC and get answer/data from it.


take a look at some part of the firmware code on my PIC:


void ProcessIO(void) { //Blink the LEDs according to the USB device status if(blinkStatusValid) { BlinkUSBStatus(); } // User Application USB tasks if((USBDeviceState < CONFIGURED_STATE)||(USBSuspendControl==1)) return; if(!HIDRxHandleBusy(USBOutHandle)) //Check if data was received from the host. { switch(ReceivedDataBuffer[0]) //Look at the data the host sent, to see what kind of application specific command it sent. { case 0x80: //Toggle LEDs command blinkStatusValid = FALSE; //Stop blinking the LEDs automatically, going to manually control them now. if(mGetLED_1() == mGetLED_2()) { mLED_1_Toggle(); mLED_2_Toggle(); } else { if(mGetLED_1()) { mLED_2_On(); } else { mLED_2_Off(); } } break; case 0x81: //Get push button state ToSendDataBuffer[0] = 0x81; //Echo back to the host PC the command we are fulfilling in the first byte. In this case, the Get Pushbutton State command. if(sw3 == 1) //pushbutton not pressed, pull up resistor on circuit board is pulling the PORT pin high { ToSendDataBuffer[1] = 0x01; } else //sw3 must be == 0, pushbutton is pressed and overpowering the pull up resistor { ToSendDataBuffer[1] = 0x00; } if(!HIDTxHandleBusy(USBInHandle)) { USBInHandle = HIDTxPacket(HID_EP,(BYTE*)&ToSendDataBuffer[0],64); } break; case 0x37: //Read POT command. Uses ADC to measure an analog voltage on one of the ANxx I/O pins, and returns the result to the host { WORD_VAL w; if(!HIDTxHandleBusy(USBInHandle)) { mInitPOT(); w = ReadPOT(); //Use ADC to read the I/O pin voltage. See the relevant HardwareProfile - xxxxx.h file for the I/O pin that it will measure. //Some demo boards, like the PIC18F87J50 FS USB Plug-In Module board, do not have a potentiometer (when used stand alone). //This function call will still measure the analog voltage on the I/O pin however. To make the demo more interesting, it //is suggested that an external adjustable analog voltage should be applied to this pin. ToSendDataBuffer[0] = 0x37; //Echo back to the host the command we are fulfilling in the first byte. In this case, the Read POT (analog voltage) command. ToSendDataBuffer[1] = w.v[0]; //Measured analog voltage LSB ToSendDataBuffer[2] = w.v[1]; //Measured analog voltage MSB USBInHandle = HIDTxPacket(HID_EP,(BYTE*)&ToSendDataBuffer[0],64); } } break; } //Re-arm the OUT endpoint for the next packet USBOutHandle = HIDRxPacket(HID_EP,(BYTE*)&ReceivedDataBuffer,64); } }//end ProcessIO


As you see it is ProcessIO function, with its main switch statement, for example case 0x37: means if it gets this value from host, then it must send value of the Potentiometer to USB host.


Now, what i tried to do is, in the VISA Interactive Control, i selected the Interface I/O tab, and then tried to send the request with the value 0x37 in the wValue field, the bmRequestType was 0x0, and what i get is weird values which i dont think are actual values of the Potentiometer reading.. (i tried change potentiometer, then do request again, and got same values)


also i tried to experiment with Basic I/O tab, and got same weird things... this stage, what am i doing wrong? what do i have to/supposed to do now?


or could u point me to valuable information source?


or the LabView Guru's on this website, say me please your opinion about this? Smiley Happy

0 Kudos
Message 1 of 25

OK! i will make it more clear..


So, without LabView, my Host application for example sends 64 byte data packet to Device, the second byte has the value 0x37, once the Device received this, it replies with the same 64 byte message in which 3rd and 4th bytes have the data needed by Host.


Then, Host application just uses those 3rd and 4th bytes for its purpose.


So, hardware works good with software. I uninstalled that driver, and successfully installed the VISAs driver, and now i want to realise the same schematic in LabView... so any ideas how can i do it? Or point me?



0 Kudos
Message 2 of 25

First, I would like to remind you that this is a holiday and you are not likely to get many response.


Second, there are a series of posts about USB communication that you should read. The first one is here.


Third, I don't understand at all why you would discard a working driver for the HID class and use VISA. Why don't you keep the working driver and interface to HID.dll with the call library function node?

Message 3 of 25

First, I would like to remind you that this is a holiday and you are not likely to get many response.


>> Well, then thank You that for replying me during a holiday, and happy new year! Smiley Happy


Second, there are a series of posts about USB communication that you should read. The first one is here.

>> I will study it now, it didnt hit my eye before. Smiley Happy


Third, I don't understand at all why you would discard a working driver for the HID class and use VISA. Why don't you keep the working driver and interface to HID.dll with the call library function node?


>> Could you tell me more about this? other words i can use some built in library functions of LabView to communicate with HID device with specific PID and VID by talking with HID.dll (in C:\windows\system32) right?




So as i see there are two ways to do this job:

1. Having VISA generate driver for you, and then write down a VI which would talk to that driver...right?


2. Call library functions talking with HID.dll


In the method 1, do i have to use NI-VISA programmers reference manual? Or something else?



In method 2, do i have to use this manual: - Using External Code in LabView ? Is that correct place to start with?










0 Kudos
Message 4 of 25

Ok, im surfing the web and NI website in order to find at least one example dealing with USB, which does something using call library function node... no luck..


so what i am doing now i created the vi, and in the block diagram placed call library function node, and lets say now i want at least read a string from my device, a product string. but im unsure exactly about what values does that element need as input...since im only reading...but LabView says its kinda error and does not execute...


again if there would be at least any example, or if someone knows about call library function node interfacing with HID.DLL could you please point me? that would help alot...


(do you really think choosing this method of USB communication would be faster/easier than using custom driver created by VISA?)



0 Kudos
Message 5 of 25
I'm not sure which will be easier. Since your firmware makes some references to HID, I would have thought you could save some time by using HID.dll and that you had some examples to use that already.
Message 6 of 25

yes, i do have a system now which works, but it has nothing to do with LabView. It is a C++ application which talks to HID driver and controls/gets data from my custom board with PIC.


Now i want to make LabView to talk with my board...and its really weird how come NI not post or show at least some examples for such a demanding and mostly used field as USB communication. Its really bad, so it seems to me that NI mostly wants people to buy their ready made boards...thats not kinda good thing.


ok will do a little more research...i stil undecided which method to use...VISA or cal library function DLL, im new to LabView... (and absolutely dont like the fact that some people prefer using it...since most of the job can be done without it, even if it requires more low level programming/design...but at the end u get a custom system which u know how it works....) ok so...


if someone might done that before, or has any example, or at least has any valuable OPINION about how is it better to implement this work in my case, please share this opinion with me, any kind of advice will be appreciated.

0 Kudos
Message 7 of 25

Hello cyrax,


I think that what Dennis is trying to offer is the idea that if you already have a piece of code that interfeaces with your hardware (this HID.dll), then you should use that code inside of LabVIEW.  The way you do this is with the Call Library Node.  I know that you are new to LabVIEW, so keep posting if you run into any problems, but a great step by step on how to do this is in the LabVIEW help. 


You can browse to it by going to Fundamentals»Calling Code Written in Text-Based Programming Languages»Concepts»Calling Shared Libraries.  Dennis or cyrax, if I missed anything (as I am not familiar with this device), just post back.  Hope this helps!

Field Engineer
0 Kudos
Message 8 of 25

Ok, i've read that manual, it seems a little bit clear...the overall idea.. now back to practice, here is the attached diagram of what i've created..


the idea is simple for now, read the VID/PID of the USB device using the HID.DLL void  HidD_GetAttributes(CStr arg1); function...


now, as i'm reading the manual for Call Function Library, there is a description:

param 1..n are example input parameters of the library function. 

param 1..n output are example output parameters of the library function. 


as u see from the block diagram, im not using input, i have configured this Call Library Function element to have one argument, arg1, and connected it to the srting module (which is in front see the string obtained from USB device)


but when i want to run it, system shows error:


One or more required inputs to this function are not wired or are wired incorrectly. Show the Context Help window to see what the connections to this function should be.


I took a look again...and it is like that... this function stores result in string and i drive it to string element... what does it want me to connect to it? 


This kind of thing is a little not straghtforward.. im sure im doing something wrong, the thing is even by following this manuals and trying to do simples thing from scratch i get stucked...


thats why i say its bad NI doesnt provide simple examples for such a most usable area...


Ok, any thoughts? i'll do research too and try again...but if anyone has idea, let me know please?

0 Kudos
Message 9 of 25

ok some corrections...first i had to call   HidD_GetHidGuid function, and obtain the Hid GUID, i connected now output of Call Library Function code to a numeric indicator.. however, even after successfull run it gives me another runtime error:



LabVIEW:  An exception occurred within the external code called by a Call Library Function Node. The exception may have corrupted LabVIEW's memory. Save any work to a new location and restart LabVIEW.


Now here is a little strange thing...cuz it doesnt even talk what is wrong... well..

0 Kudos
Message 10 of 25