STM32f4 HID receive data - usb

How to receive OUT report data from HOST PC in STM32f407 discovery board running as HID(USB) in device mode?
Is it possible?
I am thinking to send data from host using hidapi.

There is an official USB library. It is not easy, but you may try to run the examples and adapt them to your needs.
http://www.st.com/en/embedded-software/stsw-stm32046.html
Be careful with clock settings. I experienced problems with that. Here are the values I setup in system_stm32f4.c:
HSE = 8000000
PLL_M = 8
PLL_Q = 7
PLL_N = 336
PLL_P = 4
HSE is the crystal on the board. It replaces the embedded clock on the MCU. The other settings are slightly different from the values in the original configuration file. Here are the calculations of the different clocks:
PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N
= 8000000 / 8 * 336 = 336000000
USB OTG FS, SDIO and RNG Clock = PLL_VCO / PLLQ
= 336000000 / 7
= 48000000
SYSCLK = PLL_VCO / PLL_P
= 336000000 / 4
= 84000000
HCLK = SYSCLK / 1
= 84000000
PCLK2 = HCLK / 1
= 84000000
PCLK1 = HCLK / 2
= 84000000 / 2
= 42000000
The “USB OTG FS” clock HAS to be >= 48MHz if you use USB FS. Otherwise the device won't be recognized.

Related

How to setup two USRPs B210 in GNU Radio

I am trying to setup two USRP B210 with external Octoclock in GNU Radio in order to achieve 4 RX channels.
What is the right way?
1.One USRP source with Num Mboards = 2, and Num Channels = 4.
or
2.Two USRP source, each with Num Mbords = 1, and Num Channels = 2.
1.One USRP source with Num Mboards = 2, and Num Channels = 4.
Probably can't do that, UHD's multi_usrp doesn't deal with multiple b2xx devices, so only your other option
2.Two USRP source, each with Num Mbords = 1, and Num Channels = 2.
works.

LoRa, SX1276 transmission power managment

I want to verify if my information about the Tx output power is correct or no, because i'm kinda confused, so if you could bear with me to tell you want i know or at least what i think it's true about this subject:
+ in Tx they are 3 power modes:
1- RFO: from -4 dBm to 15 dBm (Pout=Pmax-(15-OutputPower) = 10.8 + 0.6 * 7 - (15 - 15) = 15) 7 is the max value for the MaxPower and 15 is the max value for the outputPower so that's way the RFO can reach 15 dBm, but i don't know why they said it's only +14dBm? and set the PaSelect to 0 to use this mode and make sure the PA_Dac set to 0x04 (default value)
2- PA_Boost: from 2 dBm to 17 dBm (Pout=17-(15-OutputPower)) this is clear. set PaSelect bit to 1 to activate this mode. and make sure to set the PA_Dac to 0x04 (default value) (PA_DAC register = 0x84)
3- +20dBm: 20 dBm, to use this option we need to be in the PA_Boost mode (set PA_Boost bit to 1) and set the PA_DAC to 0x07 (PA_DAC register = 0x87).
About the RFO where i need to set 2 variable "MaxPower" and "Output Power", i don't know what is the right way to do that, i mean which one should i adjust to get the Tx power the user want to use. or should i set the "MaxPower" to 7 so the Pmax = 15 and from there i set the "Output Power" to get the Pout (which is the Tx power) the user wants, because it's gonna be easy to go from 15 to 0 by step of 1 dBm. hope one of you have a better solution?!
Now the last thing, the OCP, which is require for the PA_Boost and +20 dBm option because both works in high power (PA_HP) and i don't know how to set that register, i mean how to calculate Imax. i need help about this, and do i need to set this register for the RFO mode too?? if yes then how? (by the way, i know about the table of OCP in the datasheet and how to calculate the OCP from Imax, the problem that i don't know how to get or figure about the Imax.
One last question, is the order to configure the PaSelect Variable and MaxPower and Output Power and PA_DAC register and OCP register matters, my real confusion is about PaSelect variable and Output Power variable and PA_DAC register configuration order.
I hope i was clear and i will appreciate your help to correct me and confirm my information. Thank YOU.
Ok, to answer some of my questions:
what i said about RFO was right, but i still don’t know why they said it’s between -4 to 14 dBm and in the same datasheet in other section they said it’s 15 dBm. anyway, about how to set this in the register because you have 2 variable you need to set (maxPower, and outoutPower), you can notice we have 2 regions, from -4 to 0 dbm and from 0 to 15 dBm. for [-4, 0[ set the maxPower to 0 and that will give you a Pmax = 10.8 and from this equation Pout = Pmax - 15 + outputPower = 10.8 -15 + outputPower = -4.2 + outputPower, we can find outputPower = Pout + 4.2, and for the region [0, 15] we set the maxPower to 7 (the max value) so we will have this now , Pout = 15 - 15 + outputPower = outputPower.
About the PA_BOOST it a forward calculation nothing fancy, outputPower = Pout - 2 and don’t forget Pout should be between 2 and 17.
To switch betwen RFO and PA_BOOST, set the bit 7 in PaConfig register. and disable the +20 dBm option in the Pa_Dac register.
About the +20 dBm option, it's the same as PA_BOOST but instead of Pmax = 17, Pmax = 20 so outputPower = Pout - 5 , and you need to enable the PA_BOOST and then set the PA_Dac to 0x87, 7 to enable the +20 dBm option, , note : just by setting the outputPower to 0xf (15) you will get the 20dBm, and to disable this feature just set PaDac varaible to 4 ( set the PaDac register to 0x84) to disable it.
for the OCP, they have a table that gives you how to calculate the ocp value from the Imax,
ocp-trim [0-15], Imax [45, 120 mA] , Imax = 45 + 5 * ocpTrim
ocp-trim [16-27], Imax [130, 240 mA] , Imax = -30 + 10 * ocpTrim
ocp-trim > 27, Imax = 240mA , Imax = 240 mA
and about the Imax which is the current need for the Tx we can find this in the datasheet:
RFOP = 13 dBm uses 28mA
RFOP = 7 dBm uses 20 mA
PA_BOOST = 17 dBm uses 90 mA
+20 dBm opton uses 120mA
the OCP need to be enabled if you want to use the PA_BOOS.
about the order of the settings. i will just try to set the register in order, just in case.

kannel receiving delivery issue

I'm using the following configuration on my kannel on 3 gateways, each gateway contains 2 sessions, one for sending and the other for receiving, the below is for receiving delivery status.
I have no issue with all of them till 3 months before one of them not able to pull the status, at the same time the same gateways is connected with more than 6000 clients with no issue at all.
The provider asked me to change the register_dlr=1
Any idea?
interface-version = 34
host = xx.xx.xx.xx
port = 0
receive-port = 8899
smsc-username = user
smsc-password = pass
system-type = VMA
source-addr-ton = 5
source-addr-npi = 1
dest-addr-ton = 0
dest-addr-npi = 0
keepalive = 600
reconnect-delay = 3
enquire-link-interval = 30
esm-class = 0
msg-id-type = 0x01

How to get the KY-022 Infrared Receiver module to work on NodeMCU in Lua?

I have a KY-022 IR module that I can't get to work on my NodeMCU. I've been searching for some code samples in Lua on the internet with no luck. Can anyone point me in the right direction? Any code samples would be greatly appreciate it.
At the moment I have the following code:
local pin = 4
gpio.mode(pin, gpio.OPENDRAIN, gpio.PULLUP)
gpio.trig(pin, "down", function (level, micro)
print(gpio.read(pin), level, micro)
end)
When I press a button on the remote, I get something like this:
0 0 571940709
0 0 571954086
0 0 571955257
1 0 571958694
1 0 571963275
1 0 571969917
0 0 571974347
0 0 571980989
1 0 571983203
1 0 571987709
0 0 571993359
1 0 572000078
0 0 572004508
0 0 572047513
0 0 572058674
So, how do I get from that to figuring out which key was pressed on the remote?
After a month or so i've reopened this project and played around with it some more. As piglet suggested, I started listening for both high and low signals. The data is still very inconsistent and can't get a stable reading.
(And by the way, thanks for the vote-down piglet, that was greatly appreciated. I wish you could have seen my search history before you decided that i'm ignorant)
I'm going to post my curent code maybe somebody can point out what I'm doing wrong here.
local pin = 4
local prevstate = false
local prevmicro = 0
local prevtime = 0
local count = 0
gpio.mode(pin, gpio.INT)
gpio.trig(pin, "both", function (level, micro)
--local state = gpio.read(pin)
local state = level
if (micro - prevmicro) > 90000 then
prevmicro = 0
prevstate = false
count = 0
print("\n#", "st", "lv", "microtime", "timing")
end
if prevstate ~= state then
time = math.floor((micro - prevmicro)/100)
prevstate = state
prevmicro = micro
if time > 3 and time < 1000 then
if prevtime > 80 and prevtime < 100 then
if time > 17 and time < 25 then
print('Repeat')
elseif time > 40 and time < 50 then
print('Start')
end
else
print(count, gpio.read(pin), level, micro, time)
count = count + 1
end
prevtime = time
end
end
end)
and here are some sample readouts from pushing the same button:
# st lv microtime timing
1 1 1 1504559531 16
2 1 0 1504566995 74
3 0 1 1504567523 5
4 1 0 1504573619 60
5 0 1 1504587422 138
6 1 0 1504588011 5
7 1 1 1504604250 162
8 1 0 1504605908 16
9 1 1 1504659929 540
10 1 0 1504662154 22
# st lv microtime timing
1 1 1 1505483535 16
2 1 0 1505491003 74
3 0 1 1505491558 5
4 1 0 1505497627 60
5 0 1 1505511409 137
6 1 0 1505512023 6
7 1 1 1505518186 61
8 1 0 1505527733 95
9 1 0 1505586167 22
10 1 1 1505586720 5
# st lv microtime timing
1 1 1 1507990937 16
2 1 0 1507998405 74
3 0 1 1507998934 5
4 1 0 1508005029 60
5 0 1 1508018811 137
6 1 0 1508019424 6
7 1 1 1508035641 162
8 1 0 1508037322 16
9 1 1 1508091345 540
10 1 0 1508093570 22
As it turns out, the Lua code required for this is actually quite simple.
Where the code above is falling over is actually the print statements. These are extremely expensive and basically, kill your sampling resolution until it's useless.
You are in essence, writing an interrupt service routine, you have a limited time budget before you have to read the next edge change and if it happens before you are done processing, tough luck! So you need to make the ISR as efficient as you can.
In the example below, we listen to the "both" edge event, when one occurs, we simply record an indication of which edge and what duration.
Periodically (using a timer) we print out the contents of the waveform.
This perfectly matches the waveform on my logic analyzer, you still have the challenge of decoding the signal. Though, there are lots of great protocol docs that explain how to take accurate waveform data and use it to determine the signal being sent. I found that a lot of cheap "brand x" remotes appear to be using the NEC protocol, so this might be a good place to start depending on your project.
IR transmission because of its nature is not completely error-free so you may get a spurious edge signal from time to time but the code below is pretty stable and runs quite well in isolation, I have yet to test it when the Microcontroller is under more load than just listening for IR.
It may turn out that using Lua for this purpose is not the best due to the fact that it is an interpreted language (each command issued is parsed and then executed at runtime, this is not at all efficient.) But I will see how far I can get before I decide to write a c module.
local irpin = 2
local lastTimestamp = 0
local waveform = {}
local i = 1
gpio.mode(irpin,gpio.INT)
gpio.trig(irpin, "both", function(level, ts)
onEdge(level, ts)
end)
function onEdge(level, ts)
waveform[i] = level
waveform[i+1] = ts - lastTimestamp
lastTimestamp = ts
i = i+2
end
-- Print out the waveform
function showWaveform ()
if table.getn(waveform) > 65 then
for k,v in pairs(waveform) do
print(k,v)
end
i = 1;
waveform = {}
end
end
tmr.alarm(0, 1000, 1, showWaveform)
print("Ready")
The following code works for my 17 key remote which came with my cheap KY-022 module. I just finished it and haven't had time to clean it up nor to optimize it, so bear with me.
local IR = 2
local lts, i, wave = 0, 0, {}
local keys = {}
keys['10100010000000100000100010101000'] = '1'
keys['10001010000000100010000010101000'] = '2'
keys['10101010000000100000000010101000'] = '3'
keys['10000010000000100010100010101000'] = '4'
keys['10000000000000100010101010101000'] = '5'
keys['10101000000000100000001010101000'] = '6'
keys['10101010000000000000000010101010'] = '7'
keys['10100010001000000000100010001010'] = '8'
keys['10100000100000000000101000101010'] = '9'
keys['10100000101000000000101000001010'] = '0'
keys['10001010001000000010000010001010'] = '*'
keys['10100010100000000000100000101010'] = '#'
keys['10000000101000000010101000001010'] = 'U'
keys['10000000100000000010101000101010'] = 'L'
keys['10001000101000100010001000001000'] = 'R'
keys['10001000001000100010001010001000'] = 'D'
keys['10000010101000000010100000001010'] = 'OK'
local function getKey()
local data = ''
local len = table.getn(wave)
if len >= 70 then
local pkey = 0
local started = false
for k, v in pairs(wave) do
v = math.floor(v/100)
if (pkey == 87 or pkey == 88 or pkey == 89) and (v > 40 and v < 50) then
started = true
end
pkey = v
if started then
if v > 300 then
started = false
end
--this is just to fix some random skipped edges
if (v > 20 and v < 25) or v == 11 then
if v > 20 and v < 25 then
d = 17
else
d = 6
end
v1 = v - d
data = data .. '' .. math.floor(v1/10)
v2 = v - (v - d)
data = data .. '' .. math.floor(v2/10)
else
if v < 40 then
data = data .. '' .. math.floor(v/10)
end
end
end
end
control = data:sub(0, 32)
if control == '00000000000000000101010101010101' then
data = data:sub(32, 63)
print(len, data, keys[data] or '?')
end
end
lts, i, wave = 0, 0, {}
end
local function onEdge(level, ts)
local time = ts - lts
wave[i] = time
i = i + 1
if time > 75000 then
tmr.alarm(0, 350, 0, getKey)
end
lts = ts
end
gpio.mode(IR,gpio.INT)
gpio.trig(IR, "both", onEdge)
I'm putting this asside and start working on some other parts of my project for the moment, but if anyone has any suggestions on how I could improve it, make it faster, smaller even, leave a comment.
PS: for those that are going to complain about not working for them, you need to adjust the if statement values for the started variable based on your remote timings. In my case it's always 88 or 89 followed by 44.
You have to get the sequence sent by the remote for each button.
Record the IR emitter's on-off sequence by logging the time stamps for high-low and low-high transitions.
Note the various patterns for each button you want to use or emulate.
Here's a in-depth tutorial http://www.instructables.com/id/How-To-Useemulate-remotes-with-Arduino-and-Raspber/
You can find this and similar resources using www.google.com

Difficulty connecting to an ntp time server

I am trying to use the following piece of code to connect to a time server and attain the time but have had no luck:
Dim ntpServer As String = "time.windows.com"
Dim ntpData(47) As Byte
Dim addresses = Dns.GetHostEntry(ntpServer).AddressList
Dim EndP As IPEndPoint = New IPEndPoint(addresses(0), 123)
Dim soc As Socket = New Socket(AddressFamily.InterNetwork, _
SocketType.Dgram, ProtocolType.Udp)
soc.Connect(EndP)
soc.Send(ntpData)
soc.Receive(ntpData)
soc.Close()
Tracing through the program I can't get past the following line of code soc.Receive(ntpData). What am I doing wrong?
Thanks
you need to provide some basic information to the server:
ntpData(0) = 27
ntpData(0) contains a section called firstByteBits.
This section needs to be set before sending the data to query for a reply.
First byte is
0 1 2 3 4 5 6 7
+-+-+-+-+-+-+-+-+
|LI | VN |Mode |
LI = leap indicator (0 in sent data)
VN = version number (3, bits 3 and 4 set)
Mode = Mode (client mode = 3, bits 6 and 7 set)
00011011 = 27 = 0x1B
And possibly a better NTP server. The time.windows.com:123 server pool is known to
be slow, sometimes not responding for a while, and of low accuracy. Better: pool.ntp.org:123 (but please read what's written on poo.ntp.org about regular use).
e.g. RFC 5905 for more details.