AutoIt DllCall to USB - dll

I am having trouble with AutoIt's DLLCall.
I am trying to control a Delcom USB Indicator LED Light using AutoIT. To do this, I have a .dll which includes the following functions:
DelcomGetDeviceCount: returns the number of Delcom USB devices
DelcomGetNthDevice: searches for specified device type, gets string of device name
DelcomOpenDevice: takes device name and returns handle to the USB device
DelcomLEDControl: takes USB handle, sets state of the LED
Here is a link to the documentation on these DLL functions.
I think my problem is not formatting the pointer to the device name correctly, because my call to DelcomGetNthDevice returns 0, failure to find device, even though I detect one device using DelcomGetDeviceCount.
I have tried
Local $handleDLL = DLLOpen("C:\DelcomDLL.dll")
Local $stString = DllStructCreate("wchar Name[512]")
Local $devices = DllCall($handleDLL,"dword","DelcomGetDeviceCount","dword",0)
Local $result = DllCall($handleDLL,"dword","DelcomGetNthDevice","dword",1,"dword",0,"ptr",DllStructGetPtr($stString))
Local $handleUSB = DllCall($handleDLL,"handle","DelcomOpenDevice","str",DllStructGetData($stString,"Name"),"dword",0)
Local $result2 = DllCall($handleDLL,"dword","DelcomLEDControl","handle",$handleUSB[0],"dword",0,"dword",1)
MsgBox(0,"# of Devices",$devices[0])
MsgBox(0,"Bool Found Device",$result[0])
DllClose($handleDLL)
and
Local $handleDLL = DLLOpen("C:\Users\b46020\Documents\Asher Project\DelcomDLL.dll")
Local $stString
Local $devices = DllCall($handleDLL,"dword","DelcomGetDeviceCount","dword",0)
Local $result = DllCall($handleDLL,"dword","DelcomGetNthDevice","dword",1,"dword",0,"str*",$stString)
Local $handleUSB = DllCall($handleDLL,"handle","DelcomOpenDevice","str*",$stString,"dword",0)
Local $result2 = DllCall($handleDLL,"dword","DelcomLEDControl","handle",$handleUSB[0],"dword",0,"dword",1)
MsgBox(0,"# of Devices",$devices[0])
MsgBox(0,"Bool Found Device",$result[0])
DllClose($handleDLL)
but in each case I turn up 1 device but cannot get its name.
I would greatly appreciate your help.
Thanks,
Jonathan

Solved it:
Local $handleDLL = DllOpen("C:\DelcomDLL.dll")
$strName = DllStructCreate("char Name[512]")
$ptrName = DllStructGetPtr($strName)
Local $result = DllCall($handleDLL, "dword", "DelcomGetNthDevice", "dword", 0, "dword", 0, "ptr", $ptrName)
Local $handleUSB = DllCall($handleDLL, "handle", "DelcomOpenDevice", "str", DllStructGetData($strName, "Name"), "dword", 0)
Local $result2 = DllCall($handleDLL, "dword", "DelcomLEDControl", "handle", $handleUSB[0], "dword", $color, "dword", $state)
Local $closed = DllCall($handleDLL,"dword","DelcomCloseDevice","handle",$handleUSB[0])
DllClose($handleDLL)

Related

Bacula multiple storage device

It seems to be relatively a simple question. I have two mount points on bacula-sd (storage) server- one for local drive and one for s3 bucket (off side backup) and what I need is start two concurrent job at the same time on both drives. So far I have something like that in bacula devices.conf
Device {
Name = "example.prod.com"
Device Type = File
Media Type = File
Archive Device = "/data/bacula/example.prod.com"
LabelMedia = yes
Random Access = yes
AutomaticMount = yes
RemovableMedia = no
AlwaysOpen = no
Maximum Network Buffer Size = 65536
}
Device {
Name = example.prod.com-s3
Device Type = File
Media Type = File
Archive Device = "/mnt/bacula-backup-storage/example.prod.com-s3"
LabelMedia = yes
Random Access = Yes
AutomaticMount = yes
RemovableMedia = no
AlwaysOpen = no
Maximum Network Buffer Size = 65536
}
but it's probably not enough because the job started only on the first device. Do I need disk autochanger or something?
You have to change Media Type = ... parameter to be different for both Devices, i.e.
Device {
Name = "example.prod.com"
Device Type = File
Media Type = File
...
}
Device {
Name = example.prod.com-s3
Device Type = File
Media Type = S3
...
}
It won't work otherwise.

How do I make a save system for a leader board with more than 3 stats

I want to make a save system so that people don't have to restart every single time they play
I don't really know what to do so I will show you the code for my leader stats this is located in the work space
local function onPlayerJoin(player)
local leaderstats = Instance.new("Model")
leaderstats.Name = "leaderstats"
leaderstats.Parent = player
local gold = Instance.new("IntValue")
gold.Name = "JumpBoost"
gold.Value = 150
gold.Parent = leaderstats
local speed = Instance.new("IntValue")
speed.Name = "Speed"
speed.Value = 20
speed.Parent = leaderstats
local coin = Instance.new("IntValue")
coin.Name = "CloudCoins"
coin.Value = 0
coin.Parent = leaderstats
local rebirths = Instance.new("IntValue")
rebirths.Name = "Rebirths"
rebirths.Value = 0
rebirths.Parent = leaderstats
end
game.Players.PlayerAdded:Connect(onPlayerJoin)
Again I don't really know what to do so, please help.
The documentation for Data Stores is pretty good. An important warning for testing :
DataStoreService cannot be used in Studio if a game is not configured to allow access to API services.
So you will have to publish the game and configure it online to allow you to make HTTP requests and access the Data Store APIs. So be sure to look at the section in that link titled, Using Data Stores in Studio, it will walk you through the menus.
Anyways, right now, you are creating the player's starting values when they join the game. DataStores allow you save the values from the last session and then load those in the next time they join.
Roblox DataStores allow you to store key-value tables. Let's make a helper object for managing the loading and saving of data.
Make a ModuleScript called PlayerDataStore :
-- Make a database called PlayerExperience, we will store all of our data here
local DataStoreService = game:GetService("DataStoreService")
local playerStore = DataStoreService:GetDataStore("PlayerExperience")
local PlayerDataStore = {}
function PlayerDataStore.getDataForPlayer(player, defaultData)
-- attempt to get the data for a player
local playerData
local success, err = pcall(function()
playerData = playerStore:GetAsync(player.UserId)
end)
-- if it fails, there are two possibilities:
-- a) the player has never played before
-- b) the network request failed for some reason
-- either way, give them the default data
if not success or not playerData then
print("Failed to fetch data for ", player.Name, " with error ", err)
playerData = defaultData
else
print("Found data : ", playerData)
end
-- give the data back to the caller
return playerData
end
function PlayerDataStore.saveDataForPlayer(player, saveData)
-- since this call is asyncronous, it's possible that it could fail, so pcall it
local success, err = pcall(function()
-- use the player's UserId as the key to store data
playerStore:SetAsync(player.UserId, saveData)
end)
if not success then
print("Something went wrong, losing player data...")
print(err)
end
end
return PlayerDataStore
Now we can use this module to handle all of our loading and saving.
At the end of the day, your player join code will look very similar to your example, it will just try to first load the data. It is also important to listen for when the player leaves, so you can save their data for next time.
In a Script next to PlayerDataStore :
-- load in the PlayerDataStore module
local playerDataStore = require(script.Parent.PlayerDataStore)
local function onPlayerJoin(player)
-- get the player's information from the data store,
-- and use it to initialize the leaderstats
local defaultData = {
gold = 150,
speed = 0,
coins = 0,
rebirths = 0,
}
local loadedData = playerDataStore.getDataForPlayer(player, defaultData)
-- make the leaderboard
local leaderstats = Instance.new("Model")
leaderstats.Name = "leaderstats"
leaderstats.Parent = player
local gold = Instance.new("IntValue")
gold.Name = "JumpBoost"
gold.Value = loadedData.gold
gold.Parent = leaderstats
local speed = Instance.new("IntValue")
speed.Name = "Speed"
speed.Value = loadedData.speed
speed.Parent = leaderstats
local coin = Instance.new("IntValue")
coin.Name = "CloudCoins"
coin.Value = loadedData.coins
coin.Parent = leaderstats
local rebirths = Instance.new("IntValue")
rebirths.Name = "Rebirths"
rebirths.Value = loadedData.rebirths
rebirths.Parent = leaderstats
end
local function onPlayerExit(player)
-- when a player leaves, save their data
local playerStats = player:FindFirstChild("leaderstats")
local saveData = {
gold = playerStats.JumpBoost.Value,
speed = playerStats.Speed.Value,
coins = playerStats.CloudCoins.Value,
rebirths = playerStats.Rebirths.Value,
}
playerDataStore.saveDataForPlayer(player, saveData)
end
game.Players.PlayerAdded:Connect(onPlayerJoin)
game.Players.PlayerRemoving:Connect(onPlayerExit)
Hope this helps!

Multiple (4x) SPI device on rasberry pi 2 running windows 10 iot

I had successfully communicate single SPI device (MCP3008). Is that possible running multiple (4x) SPI device on raspberry pi 2 with windows 10 iot?
I'm thinking to manually connect the CS(chip select) line and activate it before calling spi function and in-active it after done the spi function.
Can it be work on windows 10 iot?
How about configure the spi chip select pin? Change the pin number during the SPI initialization? Is that possible?
Any smarter way to use multiple (4 x MCP3008 ) SPI device on windows 10 iot?
(I'm planning to monitor 32 Analogue signal which will be input to my raspberry pi 2 running windows 10 iot)
Thanks a lot!
Of course you can use as many as you want (as many GPIO pins).
You just have to indicate the device to which you are calling.
First, set the configuration of the SPI for example, using chip select line 0
settings = new SpiConnectionSettings(0); //chip select line 0
settings.ClockFrequency = 1000000;
settings.Mode = SpiMode.Mode0;
String spiDeviceSelector = SpiDevice.GetDeviceSelector();
devices = await DeviceInformation.FindAllAsync(spiDeviceSelector);
_spi1 = await SpiDevice.FromIdAsync(devices[0].Id, settings);
You can not use this pin in further actions! So now you should configure the output ports using GpioPin class, which you will use to indicate the device.
GpioPin_19 = IoController.OpenPin(19);
GpioPin_19.Write(GpioPinValue.High);
GpioPin_19.SetDriveMode(GpioPinDriveMode.Output);
GpioPin_26 = IoController.OpenPin(26);
GpioPin_26.Write(GpioPinValue.High);
GpioPin_26.SetDriveMode(GpioPinDriveMode.Output);
GpioPin_13 = IoController.OpenPin(13);
GpioPin_13.Write(GpioPinValue.High);
GpioPin_13.SetDriveMode(GpioPinDriveMode.Output);
Always before transfer indicate device: (example method)
private byte[] TransferSpi(byte[] writeBuffer, byte ChipNo)
{
var readBuffer = new byte[writeBuffer.Length];
if (ChipNo == 1) GpioPin_19.Write(GpioPinValue.Low);
if (ChipNo == 2) GpioPin_26.Write(GpioPinValue.Low);
if (ChipNo == 3) GpioPin_13.Write(GpioPinValue.Low);
_spi1.TransferFullDuplex(writeBuffer, readBuffer);
if (ChipNo == 1) GpioPin_19.Write(GpioPinValue.High);
if (ChipNo == 2) GpioPin_26.Write(GpioPinValue.High);
if (ChipNo == 3) GpioPin_13.Write(GpioPinValue.High);
return readBuffer;
}
From: https://projects.drogon.net/understanding-spi-on-the-raspberry-pi/
The Raspberry Pi only implements master mode at this time and has 2 chip-select pins, so can control 2 SPI devices. (Although some devices have their own sub-addressing scheme so you can put more of them on the same bus)
I've successfully used 2 SPI devices in the DeviceTester project and Breathalyzer project within Jared Bienz's IoT Devices GitHub repo.
Notice, that in each project, the SPI interface descriptor is declared explicitly in the ControllerName property for the ADC and Display used in both of these projects. Detailed information around the Breathalyzer project can be found on my blog.
// ADC
// Create the manager
adcManager = new AdcProviderManager();
adcManager.Providers.Add(
new MCP3208()
{
ChipSelectLine = 0,
ControllerName = "SPI1",
});
// Get the well-known controller collection back
adcControllers = await adcManager.GetControllersAsync();
// Create the display
var disp = new ST7735()
{
ChipSelectLine = 0,
ClockFrequency = 40000000, // Attempt to run at 40 MHz
ControllerName = "SPI0",
DataCommandPin = gpioController.OpenPin(12),
DisplayType = ST7735DisplayType.RRed,
ResetPin = gpioController.OpenPin(16),
Orientation = DisplayOrientations.Portrait,
Width = 128,
Height = 160,
};

Send and Receive MIDI with Swift and CoreMIDI

I'm not very familiar with Swift/Objective-C or the Cocoa environment and I've been having a lot of trouble figuring out how to send or listen for data from a USB device with CoreMIDI. I'm trying to send the message (144, 36, 5) to my MIDI controller (an Ableton Push) which I have accomplished before using the Bitwig Studio Scripting API. I haven't been able to find much on this other than Apple's docs and they haven't been particularly helpful for me. So far I've figured out how to get a list of devices and check out their names, but beyond that I'm stuck.
What I've written so far trying to send MIDI:
var pushDevice = MIDIGetDevice(2)
var secondEntity = MIDIDeviceGetEntity(pushDevice, 1)
var pushDestination = MIDIEntityGetDestination(secondEntity, 0)
var midiPort = MIDIPortRef()
let myData : [Byte] = [ Byte(144), Byte(36), Byte(5) ]
var packet = UnsafeMutablePointer<MIDIPacket>.alloc(1)
var pkList = UnsafeMutablePointer<MIDIPacketList>.alloc(1)
packet = MIDIPacketListInit(pkList)
packet = MIDIPacketListAdd(pkList, 1024, packet, 0, 3, myData)
MIDISend(midiPort, pushDestination, pkList)
I feel like a bit of a goof for not being able to figure this out, I imagine it has to be a simple solution that I'm just not able to figure out for some reason. I don't think I'm properly constructing the MIDIPacketList or the MIDIPort, and I have no idea how to go about creating a callback and listening for MIDI messages.
I figured out how to send MIDI data by grabbing the device via it's unique ID. I'm not sure how memory management works in Swift, so keep that in mind. I will check back in later if I figure out how to properly create a callback and listen for MIDI input.
import Foundation
import CoreMIDI
var midiClient = MIDIClientRef()
var result = MIDIClientCreate("Foo Client", nil, nil, &midiClient)
var outputPort = MIDIPortRef()
result = MIDIOutputPortCreate(midiClient, "Output", &outputPort);
var endPoint = MIDIObjectRef()
var foundObj = MIDIObjectType()
result = MIDIObjectFindByUniqueID(UNIQUE_ID, &endPoint, &foundObj)
var pkt = UnsafeMutablePointer<MIDIPacket>.alloc(1)
var pktList = UnsafeMutablePointer<MIDIPacketList>.alloc(1)
let midiData : [Byte] = [Byte(144), Byte(36), Byte(5)]
pkt = MIDIPacketListInit(pktList)
pkt = MIDIPacketListAdd(pktList, 1024, pkt, 0, 3, midiData)
MIDISend(outputPort, endPoint, pktList)

Mobile Emulator Connection Failure (Merge Replication)

I am attempting to replicate a SQL CE 3.5 SP1 database but upon syncrhonization, I am thrown the following error:
"Failure to connect to SQL Server with provided connection information. SQL Server does not exist, access is denied because the IIS user is not a valid user on the computer running SQL Server, or the password is incorrect."
I am using the Windows Mobile 6 Professional emulator and the machine I am attempting to connect to is a Windows Virtual Machine running Windows XP Professional SP3. I have configured the network adapter settings for the emulator (I can access web pages), verified user permissions, double checked IIS settings, and triple checked my connection string:
SqlCeReplication rpl = null;
try
{
// Creates the replication object.
rpl = new SqlCeReplication();
// Establishes the connection string.
rpl.SubscriberConnectionString = #"Data Source = \Program Files\ParkSurvey\ParkSurvey.sdf; Password = *; Temp File Max Size = 512;
Max Database Size = 512; Max Buffer Size = 512; Flush Interval = 20; Autoshrink Threshold = 10; Default Lock Escalation = 100";
// Sets the Publisher properties.
rpl.PublisherSecurityMode = SecurityType.NTAuthentication;
rpl.Publisher = "PUBLISHER";
rpl.PublisherLogin = "INDICOPUBLIC\\subuser";
rpl.PublisherPassword = "*";
rpl.PublisherDatabase = "PUBLISHER";
rpl.Publication = "ParkSurveyPublication";
// Sets the internet replication properties.
rpl.InternetUrl = "http://replication/sqlce/sqlcesa35.dll";
rpl.InternetLogin = "INDICOPUBLIC\\subuser";
rpl.InternetPassword = "*";
rpl.ConnectionManager = true;
// Sets the Distributor properties.
rpl.Distributor = "PUBLISHER";
rpl.DistributorLogin = "INDICOPUBLIC\\subuser";
rpl.DistributorPassword = "psrAdmin";
rpl.DistributorSecurityMode = SecurityType.NTAuthentication;
// Sets the timeout properties.
rpl.ConnectionRetryTimeout = 120;
rpl.ConnectTimeout = 6000;
rpl.ReceiveTimeout = 6000;
rpl.SendTimeout = 6000;
// Sets the Subscriber properties.
rpl.Subscriber = "ParkSurveySubscriber";
rpl.HostName = "Mobile1";
rpl.CompressionLevel = 6;
rpl.ExchangeType = ExchangeType.BiDirectional;
// Call the replication methods.
rpl.Synchronize();
}
catch (SqlCeException sqlEx)
{
MessageBox.Show(sqlEx.Message);
}
finally
{
// Disposing the replication object
if (rpl != null)
{
rpl.Dispose();
}
}
I have also attempted to open the host machine itself in File Explorer on the mobile emulator and am prompted that "The network path was not found.". This leads me to believe it is ActiveSync issue within the emulator itself. Does anyone have any advice?
Try with IP adresse instead of hostname, and test the agent URL from IE on the device. Make sure to use the latest build of 3.5 SP2 on all components if your DB server is SQL 2012