How do i record JANUS signal as wav file? - unetstack

I am testing an interoperability between modems. one of my modem did support JANUS and I believe UnetStack base Subnero Modem Phy[3] also support JANUS. How can i send and record JANUS signal which i can use for preliminary testing for other modem ? Can someone please provide basic snippet ?

UnetStack indeed has an implementation of JANUS that is, by default, configured on phy[3].
You can check this on your modem (the sample outputs here are from unet audio SDOAM, and so your modem parameters might vary somewhat):
> phy[3]
« PHY »
[org.arl.unet.phy.PhysicalChannelParam]
fec = 7
fecList ⤇ [LDPC1, LDPC2, LDPC3, LDPC4, LDPC5, LDPC6, ICONV2]
frameDuration ⤇ 1.1
frameLength = 8
janus = true
[org.arl.yoda.FhbfskParam]
chiplen = 1
fmin = 9520.0
fstep = 160.0
hops = 13
scrambler = 0
sync = true
tukey = true
[org.arl.yoda.ModemChannelParam]
modulation = fhbfsk
preamble = (2400 samples)
threshold = 0.0
(I have dropped a few parameters that are not relevant to the discussion here to keep the output concise)
The key parameters to take note of:
modulation = fhbfsk and janus = true setup the modulation for JANUS
fmin = 9520.0, fstep = 160.0 and hops = 13 are the modulation parameters to setup fhbfsk as required by JANUS
fec = 7 chooses ICONV2 from the fecList, as required by JANUS
threshold = 0.0 indicates that reception of JANUS frames is disabled
NOTE: If your modem is a Subnero M25 series, the standard JANUS band is out of the modem's ~20-30 kHz operating band. In that case, the JANUS scheme is auto-configured to a higher frequency (which you will see as fmin in your modem). Do note that this frequency is important to match for interop with any other modem that might support JANUS at a higher frequency band.
To enable JANUS reception, you need to:
phy[3].threshold = 0.3
To avoid any other detections from CONTROL and DATA packets, we might want to disable those:
phy[1].threshold = 0
phy[2].threshold = 0
At this point, you could make a transmission by typing phy << new TxJanusFrameReq() and put a hydrophone next to the modem to record the transmitted signal as a wav file.
However, I'm assuming you would prefer to record on the modem itself, rather than with an external hydrophone. To do that, you can enable the loopback mode on the modem, and set up the modem to record the received signal:
phy.loopback = true # enable loopback
phy.fullduplex = true # enable full duplex so we can record while transmitting
phy[3].basebandRx = true # enable capture of received baseband signal
subscribe phy # show notifications from phy on shell
Now if you do a transmission, you should see a RxBasebandSignalNtf with the captured signal:
> phy << new TxJanusFrameReq()
AGREE
phy >> RxFrameStartNtf:INFORM[type:#3 rxTime:492455709 rxDuration:1100000 detector:0.96]
phy >> TxFrameNtf:INFORM[type:#3 txTime:492456016]
phy >> RxJanusFrameNtf:INFORM[type:#3 classUserID:0 appType:0 appData:0 mobility:false canForward:true txRxFlag:true rxTime:492455708 rssi:-44.2 cfo:0.0]
phy >> RxBasebandSignalNtf:INFORM[adc:1 rxTime:492455708 rssi:-44.2 preamble:3 fc:12000.0 fs:12000.0 (13200 baseband samples)]
That notification has your signal in baseband complex format. You can save it to a file:
save 'x.txt', ntf.signal, 2
To convert to a wav file, you'll need to load this signal and convert to passband. Here's some example Python code to do this:
import numpy as np
import scipy.io.wavfile as wav
import arlpy.signal as asig
x = np.genfromtxt('x.txt', delimiter=',')
x = x[:,0] + 1j * x[:,1]
x = asig.bb2pb(x, 12000, 12000, 96000)
wav.write('x.wav', 96000, x)
NOTE: You will need to replace the fd and fc of 12000 respectively, by whatever is the fs and fc fields in your modem's RxBasebandSignalNtf. For Unet audio, it is 12000 for both, but for Subnero M25 series modems it is probably 24000.
Now you have your wav file at 96 kSa/s!
You could also plot a spectrogram to check if you wanted to:
import arlpy.plot as plt
plt.specgram(x, fs=96000)

I have an issue while recording the signal. Modem refuse to send the JANUS frame. It looks like something is not correctly set on my end, specially fmin = 12000.0 , fstep = 160.0 and hops = 13. The Actual modem won't let me set the fmin to 9520.0 and automatically configured on lowest fmin = 12000. How can i calculate corresponding parameters for fmin=12000.
Although your suggestion do work on the unet audio.
Here is my modem logs:
> phy[3]
« PHY »
[org.arl.unet.DatagramParam]
MTU ⤇ 0
RTU ⤇ 0
[org.arl.unet.phy.PhysicalChannelParam]
dataRate ⤇ 64.0
errorDetection ⤇ true
fec = 7
fecList ⤇ [LDPC1, LDPC2, LDPC3, LDPC4, LDPC5, LDPC6, ICONV2]
frameDuration ⤇ 1.0
frameLength = 8
janus = true
llr = false
maxFrameLength ⤇ 56
powerLevel = -10.0
[org.arl.yoda.FhbfskParam]
chiplen = 1
fmin = 12000.0
fstep = 160.0
hops = 13
scrambler = 0
sync = true
tukey = true
[org.arl.yoda.ModemChannelParam]
basebandExtra = 0
basebandRx = true
modulation = fhbfsk
preamble = (2400 samples)
test = false
threshold = 0.3
valid ⤇ false
> phy << new TxJanusFrameReq()
REFUSE: Frame type not setup correctly
phy >> FAILURE: Timed out

Related

UDP hole punching is working with google colab but not other local nats

I'm making an p2p application with c. I made basic program which communicates peer by udp hole punching. Now my program works fine when I run a program from my PC an another from google colab.
But when tried it with my friend's pc which under another ISP (different ISP from mine) it doesn't work. Again if my friend tries it with google colab it works fine.
I tried stun test in my pc, colab, and my friends results are like these:
Mine:
test I = 1
test II = 0
test III = 0
test I(2) = 1
is nat = 1
mapped IP same = 1
hairpin = 0
preserver port = 1
Primary: Independent Mapping, Port Dependent Filter, preserves ports, no hairpin
Return value is 0x000017
colab:
test I = 1
test II = 0
test III = 0
test I(2) = 1
is nat = 1
mapped IP same = 1
hairpin = 1
preserver port = 1
Primary: Independent Mapping, Port Dependent Filter, preserves ports, will hairpin
Return value is 0x000007
my friend's:
test I = 1
test II = 0
test III = 0
test I(2) = 1
is nat = 1
mapped IP same = 1
hairpin = 0
preserver port = 1
Primary: Independent Mapping, Port Dependent Filter, preserves ports, no hairpin
Return value is 0x000017
I used ttl 255 where pinging with my fiends nat shows required ttl of 62. Is it the cause?Ping command shows ttl 112 for google colab. I'm currently trying this program from Bangladesh.

how to receive data from mqtt and open cv video stream at the same time

My project need to receive mqtt data and videostream data at the same time. However, when my raspi receiving video data by open cv, it cant receive iOT data at the same time.
My raspi need to check if the iot data is on, and the video will not turn on and receive data.
So the piority is
iOT sensor check if there is something detected-----> video will not turn. (case 1)
iOT sensor check if there is nothing detected-------> video turn on and receive another image data.
[Update 2]
# import the necessary packages
from collections import deque
from imutils.video import VideoStream
import numpy as np
import argparse
import cv2
import imutils
import time
import serial
import struct
import paho.mqtt.client as mqtt
#subscribe mqtt publisher with topic "esp/pot"
def on_connect(client, userdata,flags, rc):
client.subscribe("/esp/pot")
#get the data from the publisher and save to integer variable "bdy"
def on_message(client, userdata, msg):
bdy=int(msg.payload)
#when disconnect stop the loop of mqtt function
def on_disconnect(client, userdata,rc=0):
client.loop_stop()
#Assign the mqtt client as client
client = mqtt.Client()
#Assign the mqtt connect function to client connect
client.on_connect = on_connect
#Assign the mqtt message function to client message
client.on_message = on_message
#set the client connect to local broker host
client.connect("localhost", 1883, 60) # localhost is the Raspberry Pi itself
#Below is setting up the OpenCV function
# construct the argument parse and parse the arguments
ap = argparse.ArgumentParser()
#get the video if path provided
ap.add_argument("-v", "--video",
help="path to the (optional) video file")
ap.add_argument("-b", "--buffer", type=int, default=0,
help="max buffer size")
args = vars(ap.parse_args())
# define detect object, in here is a green object
# define the lower and upper boundaries of the "green" color in HSV value
# ball in the HSV colorspace, then initialize the
# list of tracked points
greenLower = (25, 96, 49)
greenUpper = (39, 255, 255)
Lower = greenLower
Upper = greenUpper
#define the trace point of the object detected, here is centroid
pts = deque(maxlen=args["buffer"])
#setup the serial port for arduino, which is for another motor control
ser = serial.Serial('/dev/ttyUSB0',9600)
# if a video path was not supplied, grab the reference
# to the webcam (we use webcam in this project
if not args.get("video", False):
vs = VideoStream(src=0).start()
# otherwise, grab a reference to the video file
else:
vs = cv2.VideoCapture(args["video"])
# allow the camera or video file to warm up
time.sleep(2.0)
#initialize the integer variable "bdy" to zero
bdy = 0
# main function body, keep looping
while True:
# grab the current frame of the webcam
frame = vs.read()
# handle the frame from VideoCapture or VideoStream
frame = frame[1] if args.get("video", False) else frame
# if we are viewing a video and we did not grab a frame,
# then we have reached the end of the video
if frame is None:
break
# resize the frame, blur it, and convert it to the HSV
# color space
frame = imutils.resize(frame, width=246)
blurred = cv2.GaussianBlur(frame, (11, 11), 0)
hsv = cv2.cvtColor(blurred, cv2.COLOR_BGR2HSV)
# construct a mask for the color "green", then perform
# a series of dilations and erosions to remove any small
# blobs left in the mask
mask = cv2.inRange(hsv, Lower, Upper)
mask = cv2.erode(mask, None, iterations=2)
mask = cv2.dilate(mask, None, iterations=2)
# find contours in the mask and initialize the current
# (x, y) center of the green object
cnts = cv2.findContours(mask.copy(), cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_SIMPLE)
cnts = imutils.grab_contours(cnts)
#initial center value
center = None
#start mqtt client loop function for receiving data from broker, int variable "bdy"
client.loop_start()
#if the data from broker is not 1
if bdy != 1:
#printout bdy value for debug
print (bdy)
# only proceed if at least one contour of green object was found
if len(cnts) > 0:
# find the largest contour in the mask, then use
# it to compute the minimum enclosing circle and
# centroid
c = max(cnts, key=cv2.contourArea)
#save webcam detected object centroid to cX and cY
((x, y), radius) = cv2.minEnclosingCircle(c)
M = cv2.moments(c)
cX = int(M["m10"] / M["m00"])
cY = int(M["m01"] / M["m00"])
#locate the centre of the green object
center = (cX, cY)
# only proceed if the radius of the detected green object meets a minimum size,
# say radius >2 to remove unneccssary noise
if radius > 2:
# draw the circle and centroid on the frame,
# then update the list of tracked points
#cv2.circle(frame, (int(x), int(y)), int(radius),
#(0, 255, 255), 2)
cv2.circle(frame, center, 5, (0, 0, 255), -1)
# print x_position
print (cX)
# send the cX value to the arduino by serial port with braud rate 9600
ser.write(struct.pack('>H', cX))
# if the data from broker is not 1,
# here the broker actually just send data from sensor with digital value
# so it should be 0
else:
print("boundary detected")
#stop the client loop function from receive data for clearing the retain messsage
client.loop_stop()
# show the frame from webcam to raspberry pi screen for debug
cv2.imshow("Frame", frame)
#awaiting user press key for action
chkKey = cv2.waitKey(1) & 0xFF
# if the 'q' key is pressed, stop the main function body "while True loop"
if chkKey == ord("q"):
break
# if we are not using a video file, stop the camera video stream
if not args.get("video", False):
vs.stop()
# otherwise, release the camera
else:
vs.release()
# close all windows
cv2.destroyAllWindows()
#stop the client loop function
client.loop_stop()

Trying to use openH264 as an alternative to libX264 in FFMPEG C project

I have an application that transcodes a video frame by frame using FFMPEG and x264 encoder. I am looking to release this application but the licensing of x264 made me switch to using openh264 instead.
I managed to compile everything smoothly (openh264 then FFMPEG with enable-openh264). I am now trying to correct the encoder setup in my C code as what worked for libx264 doesn't work anymore. Unfortunately I found very limited C/C++ examples of FFMPEG/openh264, i would appreciate any link/hint.
I am using the following code (dec_ctx is the AVCodecContext of the video I am decoding)
enc_ctx->height = dec_ctx->height;
enc_ctx->width = dec_ctx->width;
enc_ctx->sample_aspect_ratio = dec_ctx->sample_aspect_ratio;
/* take first format from list of supported formats */
enc_ctx->pix_fmt = encoder->pix_fmts[0];
/* video time_base can be set to whatever is handy and supported by encoder */
enc_ctx->time_base = dec_ctx->time_base;
enc_ctx->gop_size = 120; /* emit one intra frame every twelve frames at most */
enc_ctx->max_b_frames = 16;
enc_ctx->scenechange_threshold = 0;
enc_ctx->rc_buffer_size = 0;
enc_ctx->me_method = ME_ZERO;
enc_ctx->ticks_per_frame = dec_ctx->ticks_per_frame * ifmt_ctx->streams[i]->time_base.den * ifmt_ctx->streams[i]->r_frame_rate.num/ifmt_ctx->streams[i]->r_frame_rate.den;
// Set Ultrafast profile. internal name for this preset is baseline
av_opt_set(enc_ctx->priv_data, "preset", "placebo", AV_OPT_SEARCH_CHILDREN);
I get the following errors in the output with the [OpenH264] tag:
[OpenH264] this = 0x0000000019C126C0, Warning:bEnableFrameSkip = 0,bitrate can't be controlled for RC_QUALITY_MODE,RC_BITRATE_MODE and RC_TIMESTAMP_MODE without enabling skip frame.
Output #0, mp4, to 'C:\Dev\temp\geoVid.mp4':
Stream #0:0: Video: h264 (libopenh264), yuv420p, 720x480, q=2-31, 200 kb/s, 90k tbn, 180k tbc
Stream #0:1: Audio: aac, 48000 Hz, stereo, fltp, 96 kb/s
[OpenH264] this = 0x0000000019C126C0, Warning:Actual input framerate fAverageFrameRate = 0.000000 is quite different from framerate in setting 60.000000, please check setting or timestamp unit (ms), start_Ts = 0
[OpenH264] this = 0x0000000019C126C0, Warning:Actual input framerate fAverageFrameRate = 0.000000 is quite different from framerate in setting 60.000000, please check setting or timestamp unit (ms), start_Ts = 0
The output video file just plays black frames. Any hint or link to some doc would be appreciated. I have been trying to understand these errors but not too sure how to enable "skip frame" or why it is complaining about my input framerate (this is the same input as when I encode successfully with libx264)
The warnings suggest that you have to set a framedrop mode before setting the bitrate, and because of that it is setting the bitrate to 0.

Send/Receive data via USB between Vex Cortex and .net

I'm coding in vb.net (I will accept answers in c# as I can approach this either way) and I need to send data to and receive data from a Vex Cortex. It has a USB port on it which I will be connecting to a computer to send it data via a program.
I have researched this and the .net side seems fairly straightforward. Here is the code I currently have:
Dim sensor As New SerialPort("COM1")
sensor.BaudRate = 9600
sensor.Parity = Parity.None
sensor.StopBits = StopBits.One
sensor.DataBits = 8
sensor.ReadTimeout = 300
sensor.WriteTimeout = 300
sensor.Handshake = Handshake.None
sensor.Open()
I was looking around and i found some steps to take to send data from the program, which is below:
Dim byteOut(5) As Byte
Dim byteIn(6) As Byte
Dim Voltage, i As Integer
Try
byteOut(0) = &H2 '2 bytes in output message
byteOut(1) = &H0 'should be 0 for NXT
byteOut(2) = &H0 '&H0 = reply expected &H80 = no reply expected
byteOut(3) = &HB '$HB = read battery command
sensor.Write(byteOut, 0, 4) '0 = offset into byteOut and 4 = number of bytes
'now read the reply
byteIn(0) = sensor.ReadByte ' number of bytes in message
byteIn(1) = sensor.ReadByte ' should be 0 for NXT
For i = 2 To 1 + byteIn(0) ' read rest of message
byteIn(i) = sensor.ReadByte()
Next
Voltage = byteIn(5) + byteIn(6) * 256 ' the voltage has low byte in 5 and high in 6
Console.Write(Voltage) 'display voltage
Catch ex As Exception
MsgBox(ex.ToString)
End Try
The example above is used to return battery data for an irrelevant device for this question. Basically I need to be able to read the data I send, and send data back to the computer, on the Vex Cortex.
The Cortex is coded in c and I'm using RobotC to compile and download the code to the Cortex. I can't figure out how to read the data for the life of me (example code said to do Serial.begin(9600); but this raises a compilation error in RobotC).
Can anyone assist me on how to read (and write back) data on the Cortex end of this transfer? I may need to ditch RobotC and I'm perfectly fine with that if a solution is proposed without it, so long as it's still c code.

How to initialize a DT028ATFT display

I am trying to initialize a DT028ATFT-TS display on an STM32F10B main board. The system worked with DT028TFT-TS before, but that display has been discontinued. As a result of using the new diplay, the interface also had to change from ILI9320 to ILI9341. I am now basically trying to initialize the new display in a configuration that would be equivalent to what I had before.
The problem I am facing is that the display image ends up showing horizontal streaks randomly distributed (slightly different at every startup) with a bit of a flicker. And, at times (not sure if related), it just shows the backlight and nothing else - no streaks, no test image. The test image is just one big red square (100x100) displayed at x=100, y=50. You can see the effect of the problem here: Streaked Display Image.
The following is part of the initialization code that I've used - part of it taken as such from DisplayTech's sample code offered on their website, part of it customized. I've excluded commands from the sample code that are not documented under ILI9341 (probably vendor customization) and the gamma correction parameters, just to save some space. Any help in finding out where I went wrong would be appreciated.
// DT028ATFT LCD init - ILI9341:
// Frame Rate Control
SPI_WriteCMD(0xB1);
SPI_WriteDAT(0x00); // division ratio: 1
SPI_WriteDAT(0x10); // 16 clocks per line
// Power Control
SPI_WriteCMD(0xC0);
SPI_WriteDAT(0x25); // GVDD = 4.70V
SPI_WriteCMD(0xC1);
SPI_WriteDAT(0x03); // VCL=VCI x 2, VGH=VCI x 6, VGL=-VCI x 3
// VCOM Control
SPI_WriteCMD(0xC5);
SPI_WriteDAT(0x5C); // VCOMH = 5.000 V
SPI_WriteDAT(0x4C); // VCOML = -0.600 V
SPI_WriteCMD(0xC7);
SPI_WriteDAT(0x94); // VCOMH = VMH - 44, VCOML = VML - 44
// Memory Access Control
SPI_WriteCMD(0x36);
SPI_WriteDAT(0x08); // BGR=1, Normal addr order and refresh direction
// Write CTRL Display
SPI_WriteCMD(0x53);
SPI_WriteDAT(0x24); // BCTRL=1, DD=0, BL=1
// Display Function Control
SPI_WriteCMD(0xB6);
SPI_WriteDAT(0x00); // Normal scan, V63 pos pol / V0 neg pol
SPI_WriteDAT(0xA0); // LCD normally white, G1 to G320, S720 to S1
SPI_WriteDAT(0x27); // NL = 320
SPI_WriteDAT(0x00); // PCDIV not used
// Entry Mode Set
SPI_WriteCMD(0xB7);
SPI_WriteDAT(0x06); // Normal display for G1-G320 output, Low voltage detection enabled
// Column Address Set
SPI_WriteCMD(0x2A);
SPI_WriteDAT(0x00);
SPI_WriteDAT(0x00); // Start Column = 0
SPI_WriteDAT(0x00);
SPI_WriteDAT(0xEF); // End Column = 239
// Page Address Set
SPI_WriteCMD(0x2B);
SPI_WriteDAT(0x00);
SPI_WriteDAT(0x00); // Start Page = 0
SPI_WriteDAT(0x01);
SPI_WriteDAT(0x3F); // End Page = 319
// Gamma Set
SPI_WriteCMD(0x26);
SPI_WriteDAT(0x01); // Gamma Curve 1 selected (G2.2)
// Pixel Format Set
SPI_WriteCMD(0x3A);
SPI_WriteDAT(0x55); // 16bits/pixel (RGB and MCU i/f)
// Interface Control
SPI_WriteCMD(0xF6);
SPI_WriteDAT(0x00); // image data not wrapped around (exceeding data ignored)
SPI_WriteDAT(0x00); // MSB used also as LSB for R and B (64k colours)
SPI_WriteDAT(0x00); // Disp Op Mode: internal clk, GRAM access: Sys I/F, 1 transf/pxl (16bit 64k colours)
// RGB Interface Signal Control
SPI_WriteCMD(0xB0);
SPI_WriteDAT(0xC0); // BypassMode=1, RCM=2, VSPL=0, HSPL=0, DPL=0, EPL=0
// Sleep Mode off (DC/DC conv enabled, internal osc started)
SPI_WriteCMD(0x11);
Dly100us((void*)1200);
// Display ON
SPI_WriteCMD(0x29);
// ===============================
your problem sounds like a timing issue. Have you tried reducing the frame rate? that should relax the display timing. you are setting it to 119 Hz.
are you doing a proper reset before the init?
you can compare with other implementations for the ILI9341 controller:
Example
Atmel Library

Resources