PDA

View Full Version : PIC sending ASCII keyboard characters to PC by USB?



kodiak
12th January 2017, 21:33
good evening People,

For my project it is necessary for my PIC to send characters by USB to a PC, acting like a keyboard.
I thought of doing this by using the ASCII code but I do'nt know how to make my PC respond to that.
Is it anyhow possible to make a PIC act like a keyboard? Allong with some extra components, I assume:numbness:. :pride:

towlerg
13th January 2017, 04:39
All you need is Proton basic, a PIC that has USB hardware and is supported by Proton and very little else (a USB connector, some switches and a few resistors). Typical PIC's 18f2550 and 18f1450 among many. There is an example of a USB keyboard in your samples directory. It's one of those few things that are actually easier than you thought they would be at the outset.

kodiak
14th January 2017, 21:58
Thanks towlerg.
I'll look into that.
Is a 18F series PIC programmable with a PICkit II? Or does it require the PICkit III Programmer?
I'm somewhat new in this. At least on that level. :-)


[Edit] Eehh... Where can I find the HID/USB keyboard in the Directory?
I can only seem to find a Mouse sample.
Then again... I haven't used Proton for some time and my PDS might be outdated?

SimonJA
14th January 2017, 23:06
You didn't mention which 18F pic you wanted to use but I think most should work with the Pickit 2.

If you update to the latest version you'll find USB HID Keyboard Demo in C:\Users\yourname\PDS\Samples\New Samples (in Windows 7).

kodiak
15th January 2017, 12:01
Tx SimonJA,

It seems I'll have to update PDS first. :redface:
I might have mist some updates in the past couple of months (years? :culpability:) due to inactivity.

towlerg
15th January 2017, 14:09
One area of possible confusion re. USB. There are two versions of USB available. The first is the built-in functions USBin, USBout, USBpoll and USBinit - it would appear that there isn't a keyboard descriptor supplied out of the box but I'm sure you could find one somewhere in this board. The second is a stand alone translation of MicroChip's current USB stack in new samples). This version is IMHO far superior. The only downside is that CDC is not supported. The principle upside is the descriptor format used. Because it is so close to Microchips C based version it is "easy" to translate descriptors from external sources.

BTW The term easy when applied to descriptors is relative, if you use USB much you will come to hate them but never understand them.

kodiak
18th January 2017, 20:43
I've looked into that example given in the Samples folder.
Now this might sound foolish but is that all it takes? 😳
Does my PC immediately recognize the PIC as a "keyboard"
And if so... how can I send characters to that PC using that code? 😐

towlerg
19th January 2017, 07:35
Does my PC immediately recognize the PIC as a "keyboard" yes


And if so... how can I send characters to that PC using that code? characters are send to the PC by the two byte buffer, a character and a modifier. see example
"Combining nRF24L01+ with USB - A Remote Control Application" here (http://www.protonbasic.co.uk/showthread.php/73140-Combining-nRF24L01-with-USB-A-Remote-Control-Application?p=496715&viewfull=1#post496715) (either of the first two zips are keyboard emulators). Note the file "KeyboardDefs.Inc" which translates between ASCII and keycode.

Sorry if the code I quote seems very complex, the board is short of simple USB keyboard examples. Look in particular at the routine "InvokeApp" (it sends the string "Foobar2000.exe" to the PC) and "SendKey" which shows that both press and release being sent.

kodiak
21st January 2017, 21:52
OK... Lets see if I get this correct. :untroubled:

It is indeed quite a complex code, but focussing on the "InvokeApp" things got somewhat less "foggy" for me.

First, the PC gets invoked to respond or at least accept de data which is to be send. "GoSub SendKey[keyr, LeftGUIMask]" Why that is done by the letter "R" is not clear to me, but that is something to focus on later.
The next range of Gosubs each send their own character. I get that.
What I do not get is why the Variabeles pKey and pModifier are created every time the Sub is started.
I Guess that the "Pop" command loads the letter into the Byte and in the Array "Keybuffer", the content of the Pop is then loaded in the right position, just to be send by the HID_Writearray command.
Afterwards, a Null is send in the same way, to "release" the "button".

I'll look into the POP command later on. I'm not into all the codes used and I've never worked with arrays before though I have read about it. So I have an idea...

I start to get it now...
But what is "NoModifier"? It seems it it not a command, but I cannot find it beeing a variable or something.
Besides. How does the variabele pKey know which letter is selected? There is some in the KeyboardDefs.inc/Constants, but I do not get how the program is linked to that file. The content of the file is clear, by the way.

Your input was very helpfull so far, Towlerg. I realy appriciate your expertise on this.

towlerg
21st January 2017, 23:15
You should understand that the code InvokeApp is executing a windows program - in this case an mp3 player call FooBar2000. The SendKey[keyr, LeftGUIMask] is one way to run a windows executable - try it, while pressing the windows key, press r. It should invoke a Run dialog.


What I do not get is why the Variabeles pKey and pModifier are created every time the Sub is started.
Proton does not have proceedures in the conventional sense. But it can sort of do it with a little programmer intervention. GOSUB SendKey[keyo, NoModifier] this syntax pushes the two values (keyo and NoModifiers) onto the stack and then calls the SendKey routine. SendKey pops the values off the stack (in reverse order) and then uses them as if they were passed parameters.


Afterwards, a Null is send in the same way, to "release" the "button". The same behavior as a physical keyboard.


But what is "NoModifier"? It seems it it not a command, but I cannot find it beeing a variable or something. for each key (value translated from ASCII to keycode in "KeyboardDefs.Inc") a modifier code is also sent. This is a bit field in which individual bits mean things like Shift, Control etc. - for example the only difference between r and R is that the shift bit is set in the modifier of the second one. See the end of KeyboardDefs.inc for a list of modifiers.


Besides. How does the variabele pKey know which letter is selected? There is some in the KeyboardDefs.inc/Constants, but I do not get how the program is linked to that file. The content of the file is clear, by the way. The first parameter in "GoSub SendKey[keyf, NoModifier]" is instructing SendKey to send the "f" key. The code line "Include "KeyboardDefs.Inc" adds the contents of the specified to the main source.

In hindsight it is clear to me that this is a terrible example. Tell me what you are trying to do and I'll try to come up with something clearer.

normnet
21st January 2017, 23:19
Has been answered

kodiak
22nd January 2017, 14:36
OK, I kinda get it now. At least, I think I do. :-)
The fact there is a "key" instruction (Keyf), makes the program to look into the "KeyboardDefs.inc" to figure out which code needs to be send.
This is always the case when a "Keyboard" is defined in the program? Because I could not find some redirection in the program to the KeyboardDef.Inc file.

And the NoModifier is a byte which contains nothing, to give the impression there is no extra key pressed...

My intentions are to create a Program which gives the alphanumerical characters and some extra codes as space, backspace, maybe Enter etc.
So in fact I have a series of letters and numbers in a following order which I would like to have printed on my screen.
The byte sized characters need to be translated in the correct order, before send by USB.
That is Why I was interested in the KeyboardDef.Inc file to make that "translation".

Every time a character is available, the USB-part of the program needs to recognize it, translate it en send it.
the code, creating the character, may create one every few tenths of seconds. So it is not really fast.

towlerg
22nd January 2017, 18:10
So, if I understand you correctly, you need a subroutine that accepts an ASCII character as an input parameter and makes the appropriate USB output to simulate a key depress/release?

BTW the thing that makes my example appear to the PC as a keyboard, is the descriptor.

kodiak
22nd January 2017, 21:07
So, if I understand you correctly, you need a subroutine that accepts an ASCII character as an input parameter and makes the appropriate USB output to simulate a key depress/release?


That is correct.
But it does not necessarily has to be an ASCII code.
Till now I thought it was the only way to send characters.:suspicion:
I have a series of codes which I "translate" in a subroutine to whatever is needed to send the right character.

There is no character input. Only a combination of keys (pulling ports low) that results in certain values. It is just an "if then" situation which desides which character needs to be send by USB according to the value and some other irrelevant stuff.

towlerg
23rd January 2017, 00:40
I can't test this but it should get you started,3205

kodiak
23rd January 2017, 17:12
I'll look into the code this evening.
When I have the correct PIC, I will test it.
I will keep you informed!

Les
23rd January 2017, 18:31
That's a nice piece of code George.

Simple and useful, just the way things should be IMO. :-)

towlerg
23rd January 2017, 20:00
When I have the correct PIC

Code should run on any PIC which has USB hardware and is supported by Proton.

kodiak
29th January 2017, 16:15
I'm not that familiar with the 18Fxxxx series of the PICs.
But there wil be no problem finding the right PIC.

If I understand the program correctly, the letters wil appear on my screen every second?
At least if I understand the beeing of the 1000ms correctly.

I intent to write a Select-Case sequense inwere the program only enters the sub if the correct code is detected.

towlerg
30th January 2017, 11:35
Please don't think I'm trying to teach you to suck eggs but (there's always a but isn't there) the PC needs to be running an application that would display keyboard input and the sapplication must have focus. Notepad should be fine, just type a few characters on the normal keyboard to make sure it has focus.

kodiak
30th January 2017, 21:30
Never mind,
I'll manage.
I've got a good lead now.

Btw. Congratz on bracking your 1000th post. 😉

For the record, I will reply the results on this lateron.

Kodiak

hadv215
1st February 2017, 08:58
You can force an application to run and have the focus by using Windows Menu(Control Escape), enter name of the program (this will go into the search editbox), enter.