DirectShow IBaseFilter EnumPins returns nothing - directshow

Using GraphEdit, I can add the filter to the editor and use it to render a video. When I create the instance via COM (using DirectShow.NET), the method EnumPins (followed by Next checks) returns no pins.
Is there a reason why GraphEdit would show the pins and I cannot get a reference to the pins via the COM interfaces?
EDIT: Here is the method I am using to get the first available pin (of any type). Nothing is ever returned for this filter, but I can see 4 pins (two in, two out) in graph edit.
public static IPin GetPins(IBaseFilter vSource, int iIndex)
{
IEnumPins pins;
var ppPins = new IPin[1];
if (vSource == null)
return null;
DsError.ThrowExceptionForHR(vSource.EnumPins(out pins));
try
{
while (pins.Next(1, ppPins, IntPtr.Zero) == 0)
{
return ppPins[0];
}
}
finally
{
Marshal.ReleaseComObject(pins);
}
return null;
}

Related

After I declare an object from a class, and try to set a variable to that object inly, why does it say that it does not declare a type?

I am writing code for a school project that will be used for a Chromebook charging station with security. The problem I am having now is when I am detecting if a Chromebook is actually in the slot after the user has been assigned one, I am using a rocker switch to simulate this but when I am declaring the pin to the rocker, the arduino verfier comes up with that
"'slot1' does not name a type".
Code is below:
//class
class Chromebook_slot {
public:
String Name = "";
String RFID_tag = "";
int rocker = 0;
boolean chromebook_in = false;
//class function to check if chromebook is in.
//if not, redirect already to reassigning so chromebook slot is entered as open and free.
void set_if_in()
{
int momen_1_state = digitalRead(momen_1);
int momen_2_state = digitalRead(momen_2);
// the button has been pushed down and the previous process has been completed
// eg. servos would have been reset if there was a previous user
if (momen_1_state == HIGH || momen_2_state == HIGH)
{
chromebook_in = digitalRead(this->rocker);
if (chromebook_in == 0)
{
re_assigning();
}
else
{
return;
}
}
}
};
//this is now outside the class..
//class declarations
Chromebook_slot slot1;
Chromebook_slot slot2;
//variables for rocker switches which will act for detecting chromebooks.
// in my final version, this will replaced by a photoresistor and laser.
slot1.rocker = 3;
slot2.rocker = 2;
Where the function re_assigning() is a separate function declared further in the code and just resets the slot as open for future use.
slot1.rocker = 3;
slot2.rocker = 2;
These are statements that cannot be at the top level of a C++ (or .ino) file. They need to be inside of a function. What's happening is the compiler is looking looking at the slot1 identifier through the lens of potential valid constructions. It sees an identifier, and about the only thing that could legally exist at this point in the code that starts with an identifier like that is some declaration, e.g. int a = 7;, or more abstractly some_type some_more_stuff. So it expects slot1 to be a type, which it isn't, hence the message.
If you want an assignment like those to happen early on in an Arduino program, the simplest thing you could do is put them in setup():
void setup() {
slot1.rocker = 3;
slot2.rocker = 2;
// ...
}
Or, you'd make these part of the Chromebook_slot's constructor, such that they could be given in slot1 and slot2's declaration:
class Chromebook_slot {
public:
Chromebook_slot(int rocker_init_value) {
rocker = rocker_init_value;
}
// ...
Or in a maybe less familiar but more proper form, using the constructor's initialization list:
class Chromebook_slot {
public:
Chromebook_slot(int rocker_init_value)
: rocker(rocker_init_value) {}
// ...
Once you have a constructor for Chromebook_slot, your variables can become:
Chromebook_slot slot1(3);
Chromebook_slot slot2(2);

how can i get SSID of connected wifi in android Q and later?

My code for before android Q is here
but for android Q this function return "unknown ssid".
I know that for android Q must use this ConnectivityManager.NetworkCallback and ConnectivityManager#getNetworkCapabilities and ConnectivityManager#getLinkProperties.but i cant find sample code or guid.
private String get_connected_ssid() {
String s1 = null ,s2 = null;
try {
WifiManager wifi = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
assert wifi != null;
WifiInfo wifiinfo = wifi.getConnectionInfo();
List<WifiConfiguration> listOfConfigurations = wifi.getConfiguredNetworks();
for (int index = 0; index < listOfConfigurations.size(); index++) {
WifiConfiguration configuration = listOfConfigurations.get(index);
if (configuration.networkId == wifiinfo.getNetworkId()) {
s1 = configuration.SSID;
}
}
}catch (Exception e){
e.printStackTrace();
}
/* NetworkInfo Deprecated in API level 29
Callers should instead use the ConnectivityManager.NetworkCallback API to learn about connectivity changes,
or switch to use ConnectivityManager#getNetworkCapabilities or ConnectivityManager#getLinkProperties to
get information synchronously. Keep in mind that while callbacks are guaranteed to be called for every
event in order, synchronous calls have no such constraints, and as such it is unadvisable to use the
synchronous methods inside the callbacks as they will often not offer a view of networking that is
consistent (that is: they may return a past or a future state with respect to the event being processed
by the callback). Instead, callers are advised to only use the arguments of the callbacks, possibly
memorizing the specific bits of information they need to keep from one callback to another.
*/
//getActiveNetworkInfo Deprecated in API level 29 -->useUse NetworkCallbacks instead for apps that target Android 10 (API level 29) and higher-->refrence : developer.android
//getExtraInfo() Deprecated in API level 29
try {
ConnectivityManager cm = (ConnectivityManager) getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
assert cm != null;
NetworkInfo info = cm.getActiveNetworkInfo();
if (info != null && info.isConnected()) {
}
}catch (Exception e){
e.printStackTrace();
}
return s1 + s2;
}

Serial Connection (Arduino --> Java)

this will be my first post and I will do my best to be clear and concise. I've checked some of the other posts on this forum but was unable to find a satisfactory answer.
My question pertains to the use of JavaFX and the jSSC(java simple serial connection) library. I've designed a very simple GUI application that will host four different charts. Two of the charts will display readings from temperature and solar sensors for the past hour, while the other two display that data over an extended period -- a 14-hour period. Eventually I would like to make that more flexible and set the application to "sleep" when the readings become roughly zero (night).
How can I stream data to display this data in real time?
After referencing several sources online and from "JavaFX 8 Intro. by Example", I've been able to construct most of the serial connection class. I'm having trouble processing the data readings, so that it can be displayed on the chart.
public class SerialComm implements SerialPortEventListener {
Date time = new Date();
SimpleDateFormat sdf = new SimpleDateFormat("mm");
boolean connected;
StringBuilder sb;
private SerialPort serialPort;
final StringProperty line = new SimpleStringProperty("");
//Not sure this is necessary
private static final String [] PORT_NAMES = {
"/dev/tty.usbmodem1411", // Mac OS X
"COM11", // Windows
};
//Baud rate of communication transfer with serial device
public static final int DATA_RATE = 9600;
//Create a connection with the serial device
public boolean connect() {
String [] ports = SerialPortList.getPortNames();
//First, Find an instance of serial port as set in PORT_NAMES.
for (String port : ports) {
System.out.print("Ports: " + port);
serialPort = new SerialPort(port);
}
if (serialPort == null) {
System.out.println("Could not find device.");
return false;
}
//Operation to perform is port is found
try {
// open serial port
if(serialPort.openPort()) {
System.out.println("Connected");
// set port parameters
serialPort.setParams(DATA_RATE,
SerialPort.DATABITS_8,
SerialPort.STOPBITS_1,
SerialPort.PARITY_NONE);
serialPort.setEventsMask(SerialPort.MASK_RXCHAR);
serialPort.addEventListener(event -> {
if(event.isRXCHAR()) {
try {
sb.append(serialPort.readString(event.getEventValue()));
String str = sb.toString();
if(str.endsWith("\r\n")) {
line.set(Long.toString(time.getTime()).concat(":").concat(
str.substring(0, str.indexOf("\r\n"))));
System.out.println("line" + line);
sb = new StringBuilder();
}
} catch (SerialPortException ex) {
Logger.getLogger(SerialComm.class.getName()).log(Level.SEVERE, null, ex); }
}
});
}
} catch (Exception e) {
System.out.println("ErrOr");
e.printStackTrace();
System.err.println(e.toString());
}
return serialPort != null;
}
#Override
public void serialEvent(SerialPortEvent spe) {
throw new UnsupportedOperationException("Not supported yet.");
}
public StringProperty getLine() {
return line;
}
}
Within the try block, I understand the port parameters, but the eventListener is where I am having difficulty. The significance of the stringbuilder is to append data the new data as it is read from the device.
How will I account for the two sensor readings? Would I do that by creating separate data rates to differentiate between the incoming data from each sensor??
I hope that this is clear and that I've provided enough information but not too much. Thank you for any assistance.
-------------------------------UPDATE--------------------------
Since your reply Jose, I've started to make the additions to my code. Adding the listener within the JavaFX class, I'm running into some issues. I keep getting a NullPointerException, which I believe is the String[]data not being initialized by any data from the SerialCommunication class.
serialPort.addEventListener(event -> {
if(event.isRXCHAR()) {
try {
sb.append(serialPort.readString(event.getEventValue()));
String str = sb.toString();
if(str.endsWith("\r\n")) {
line.set(Long.toString(time.getTime()).concat(":").concat(
str.substring(0, str.indexOf("\r\n"))));
System.out.println("line" + line);
sb = new StringBuilder();
}
} catch (SerialPortException ex) {
Logger.getLogger(SerialComm.class.getName()).log(Level.SEVERE, null, ex);
}
}
});
}
} catch (Exception e) {
System.err.println(e.toString());
}
I'm adding the time to the data being read. As Jose mentioned below, I've added tags to the data variables within the arduino code, I'm using: Serial.print("Solar:"); Serial.println(solarData);
Rough code of the JavaFx listener:
serialPort.getLine().addListener((ov, t, t1) -> {
Platform.runLater(()-> {
String [] data = t1.split(":");
try {
//data[0] is the timestamp
//data[1] will contain the label printed by arduino "Solar: data"
switch (data[1]) {
case "Solar":
data[0].replace("Solar:" , "");
solarSeries.getData().add(new XYChart.Data(data[0], data[1]));
break;
case "Temperature":
temperatureSeries.getData().add(new XYChart.Data(data[0], data[1]));
break;
}
Is the reason this code has NullPointerException a result of the String [] data array being uninitialized?
Exception Error
Ports: /dev/tty.usbmodem1411Connected
Exception in thread "EventThread /dev/tty.usbmodem1411" java.lang.NullPointerException
at SerialComm.lambda$connect$0(SerialComm.java:61)
at SerialComm$$Lambda$1/1661773475.serialEvent(Unknown Source)
at jssc.SerialPort$LinuxEventThread.run(SerialPort.java:1299)
The SerialPortEventListener defined in the jssc library allows listening for serial port events. One of those events is the RXCHAR event, that occurs when the Arduino board is sending some data and some bytes are on the input buffer.
event.getEventValue() returns an int with the byte count, and serialPort.readString(event.getEventValue()) get the String format from those bytes.
Note that this method does not return a full line, so you need to listen to carriage return and line feed characters. Once you find "\r\n", you can get the line, and reset the StringBuilder for the next one:
sb.append(serialPort.readString(event.getEventValue()));
String str=sb.toString();
if(str.endsWith("\r\n")){
line.set(str.substring(0,str.indexOf("\r\n")));
sb=new StringBuilder();
}
where line is an observable String:
final StringProperty line=new SimpleStringProperty("");
On the Arduino side, if you want to send values from different sensors at different rates, I suggest you define on the Arduino sketch some identification string for each sensor, and you print for each value the id of its sensor.
For instance, these will be the readings you will get with the serial event listener:
ID1,val1
ID1,val2
ID2,val3
ID1,val4
ID3,val5
...
Finally, on the JavaFX thread, define a listener to changes in line and process the String to get the sensor and the value. Something like this:
serial.getLine().addListener(
(ObservableValue<? extends String> observable, String oldValue, String newValue) -> {
Platform.runLater(()->{
String[] data=newValue.split("\\,");
if(data[0].equals("ID1"){
// add to chart from sensor 1, value data[1];
} else if(data[0].equals("ID2"){
// add to chart from sensor 2, value data[1];
} else if(data[0].equals("ID3"){
// add to chart from sensor 3, value data[1];
}
});
});
Note you need to add Platform.runLater(), since the thread that gets the data from serial port and updates line is not on the JavaFX thread.
From my experience, on the Arduino side, add a comma or something to separate the different values when you print and when you receive that string in Java simply split that string by commas.
String[] stringSeparate = str.split(",");

What is the necessary call to send data over COM port using OpenNETCF Port class?

I am trying to retrieve a value from a Zebra printer by interrogating it with this code:
public static string GetSettingFromPrinter(string cmd)
{
string setting = string.Empty;
try
{
BasicPortSettings bps = new BasicPortSettings();
bps.BaudRate = BaudRates.CBR_19200;
bps.Parity = OpenNETCF.IO.Serial.Parity.none;
bps.StopBits = OpenNETCF.IO.Serial.StopBits.one;
Port serialPort = new Port("COM1:", bps);
serialPort.Open();
byte[] sendBytes = Encoding.ASCII.GetBytes(cmd);
MessageBox.Show(Encoding.ASCII.GetString(sendBytes, 0, sendBytes.Length));
serialPort.Output = sendBytes;
serialPort.Query(); // <= this is new
byte[] responseBytes = serialPort.Input;
setting = GetString(responseBytes);
serialPort.Close();
return setting;
}
catch (Exception x)
{
MessageBox.Show(x.ToString());
return setting;
}
}
However, I don't see where the Output is actually sent, or how to do that. My best guess was calling the Port.Query() method, but that doesn't work, either - at least there is nothing in setting / the Port.Input value after doing so.
I have successfully passed commands to the printer using the older SerialPort class:
public static bool SendCommandToPrinter(string cmd)
{
bool success; // init'd to false by default
try
{
SerialPort serialPort = new SerialPort();
serialPort.BaudRate = 19200;
serialPort.Handshake = Handshake.XOnXOff;
serialPort.Open();
serialPort.Write(cmd);
serialPort.Close();
success = true;
}
catch // may not need a try/catch block, as success defaults to false
{
success = false;
}
return success;
}
...but was advised not to use that due to its longness of tooth.
I would revert back to this snaggletooth if I knew how to read from the old SerialPort class. Does anybody know what I need to do to send sendBytes (and receive responseBytes)?
UPDATE
I tested "COM1" instead of "COM1:" (I used the latter because there is a post that says the colon is necessary (<= not medical advice, although that is doubtless true in that sense, too), but sans the ":" made no noticeable difference.
I then tried "string.Empty" in place of giving it a name, and got, "OpenNETCF.IO.Serial.CommPortException: CreateFileFailed 2 ..."
Onward...or is it Sideward...
FWIW, setting the Output property immediately sends the data on the wire. No additional call is necessary.

Setting default TWAIN data source without using API UI menu

Using the twaindotnet library in C#, I'm wondering if there's a way to set the default datasource using the library.
As a feeble attempt, I've tried adding a SetDefault method to the DataSource class of twaindonet, like this
public static void SetDefault(Identity applicationId, IWindowsMessageHook messageHook, DataSource newDataSource)
{
var defaultSourceId = newDataSource.SourceId;
// Attempt to get information about the system default source
var result = Twain32Native.DsmIdentity(
applicationId,
IntPtr.Zero,
DataGroup.Control,
DataArgumentType.Identity,
Message.Set,
defaultSourceId);
if (result != TwainResult.Success)
{
var status = DataSourceManager.GetConditionCode(applicationId, null);
throw new TwainException("Error getting information about the default source: " + result, result, status);
}
}
which is called from the DataSourceManage class like this
public void SelectSource(DataSource dataSource)
{
DataSource.Dispose();
DataSource.SetDefault(ApplicationId, _messageHook, dataSource);
}
But when I try to use SetDefault, Twain32Native.DsmIdentity always results in Failure being returned.
I basically copied from SetDefault the setDefaultDataSource method from TWAIN sample Data Source and Application
pTW_IDENTITY TwainApp::setDefaultDataSource(unsigned int _index)
{
if(m_DSMState < 3)
{
cout << "You need to open the DSM first." << endl;
return NULL;
}
else if(m_DSMState > 3)
{
PrintCMDMessage("A source has already been opened, please close it first\n");
return NULL;
}
if(_index >= 0 && _index < m_DataSources.size())
{
m_pDataSource = &(m_DataSources[_index]);
// set the specific data source
TW_UINT16 twrc;
twrc = _DSM_Entry(
&m_MyInfo,
0,
DG_CONTROL,
DAT_IDENTITY,
MSG_SET,
(TW_MEMREF) m_pDataSource);
switch (twrc)
{
case TWRC_SUCCESS:
break;
case TWRC_FAILURE:
printError(0, "Failed to get the data source info!");
break;
}
}
else
{
return NULL;
}
return m_pDataSource;
}
Any help would be greatly appreciated.
The possible cause is that the version of your TWAIN DSM is too low. Only DSM 2.0 or above supports setting default TWAIN data source.

Resources