I've been playing with the new Remote Wiring libraries on Windows Remote Arduino and I have been unable to control a servo - there is a "PinMode.Servo" option in the library - but the motor does not move reliably, sometimes not at all.
The code is below
namespace UniversalBlink
{
public sealed partial class MainPage : Page
{
private bool useBluetooth = true;
BluetoothSerial bluetooth;
UsbSerial usb;
RemoteDevice arduino;
public MainPage()
{
this.InitializeComponent();
if (useBluetooth)
{
bluetooth = new BluetoothSerial("HC-06");
arduino = new RemoteDevice(bluetooth);
bluetooth.ConnectionEstablished += OnConnectionEstablished;
//these parameters don't matter for bluetooth
bluetooth.begin(0, 0);
}
else
{
usb = new UsbSerial("VID_2341", "PID_0043"); //I've written in my device D directly
var test = UsbSerial.listAvailableDevicesAsync();
arduino = new RemoteDevice(usb);
usb.ConnectionEstablished += OnConnectionEstablished;
usb.begin(57600, SerialConfig.SERIAL_8N1);
}
}
private void OnConnectionEstablished()
{
//enable the buttons on the UI thread!
var action = Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal, new Windows.UI.Core.DispatchedHandler(() => {
OnButton.IsEnabled = true;
OffButton.IsEnabled = true;
arduino.pinMode(9, PinMode.SERVO);
}));
}
private async void OnButton_Click(object sender, RoutedEventArgs e)
{
arduino.analogWrite(9, 0);
}
private async void OffButton_Click(object sender, RoutedEventArgs e)
{
arduino.analogWrite(9, 140);
}
}
}
I'm at a loss as to where to go from here.
The Code use Bluetooth or Serial (via USB) to control an Arduino.
Related
So I am pretty new to Xamarin.Android, I have managed to connect to my Bluetooth printer device using the code below, so now I want to send a print command to the printer but I have not been able to for several weeks now. Searched the internet but I have not been able to find a solution. Any assistance will be greatly appreciated
Button btnConnect;
TextView txtView;
Button btnPrint;
BluetoothSocket socket;
BluetoothAdapter adapter;
BluetoothDevice bluetoothDevice;
private byte[] buffer;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.BrianPeek);
FindViews();
HandleEvents();
buffer = new byte[1024];
}
private void HandleEvents()
{
btnConnect.Click += BtnConnect_Click;
btnPrint.Click += Print_Click;
}
private void Print_Click(object sender, EventArgs e)
{
// Variables
string ipAddress = "192.168.1.100";
int portNumber = 9100;
List<string> myText = new List<string>() { "Line1", "Line2" };
// Try to find the platform specific services
// var printer = DependencyService.Get<DSInterfaces.IPrinter>();
var printer = new Printer();
if (printer == null) {
// Do not proceed if no services found for the platform
AlertDialog.Builder alert = new AlertDialog.Builder(this);
alert.SetTitle("Printer");
alert.SetMessage("Error");
alert.Show();
}
try
{
// Call themethod, declare by the IPrinter interface
printer.Print(ipAddress, portNumber, myText);
}
catch (Exception ex)
{
AlertDialog.Builder alert = new AlertDialog.Builder(this);
alert.SetTitle("Printer");
alert.SetMessage("Failed to print redemption slip\nReason "+ex.Message);
alert.Show();
// Exception here could mean difficulties in connecting to the printer etc
//await DisplayAlert("Error", $"Failed to print redemption slip\nReason: {ex.Message}", "OK");
}
}
private async void BtnConnect_Click(object sender, EventArgs e)
{
adapter = BluetoothAdapter.DefaultAdapter;
if(adapter == null) {
AlertDialog.Builder alert = new AlertDialog.Builder(this);
alert.SetTitle("Bluetooth");
alert.SetMessage("No Bluetooth Adapter Found");
alert.Show();
}
if (!adapter.IsEnabled) {
AlertDialog.Builder alert = new AlertDialog.Builder(this);
alert.SetTitle("Bluetooth");
alert.SetMessage("Bluetooth Adapter is not set!");
alert.Show();
}
bluetoothDevice = (from bd in adapter.BondedDevices
where bd.Name == "MTP-II"
select bd).FirstOrDefault();
if (bluetoothDevice != null) {
AlertDialog.Builder alert = new AlertDialog.Builder(this);
alert.SetTitle("Bluetooth");
alert.SetMessage("Bluetooth device " + bluetoothDevice.Name );
alert.Show();
//Connect Bluetooth Device
socket = bluetoothDevice.CreateRfcommSocketToServiceRecord(UUID.FromString("00001101-0000-1000-8000-00805f9b34fb"));
await socket.ConnectAsync();
//after connection, communication occurs through input and output stream
// Read data from the device
await socket.InputStream.ReadAsync(buffer, 0, buffer.Length);
// Write data to the device
await socket.OutputStream.WriteAsync(buffer, 0, buffer.Length);
} else {
AlertDialog.Builder alert = new AlertDialog.Builder(this);
alert.SetTitle("Bluetooth");
alert.SetMessage("The device is not found");
alert.Show();
}
}
private void FindViews()
{
btnConnect = FindViewById<Button>(Resource.Id.btnConnectBlue);
txtView = FindViewById<TextView>(Resource.Id.txtText);
btnPrint = FindViewById<Button>(Resource.Id.btnConnectPrint);
}
I am working on an app that creates a mock location. Now, after I start it - everything seems to work here - and then go into maps, I always get set right to where I actually am - not where my fake coordinates are. So im thinking, this is due to my program immediately stopping as soon as i push it into the background of the android phone im debugging with.
1) Would u say so too?
2) So, how do I get my program to continue mocking the location, even though its in the background? I already set up a timer, that mocks a new location every 5 seconds. Here is my main activity (which happens to be a bit long, excuse me..)
Any help would be AWESOME!
public static double GlobalLongitude = 0.0; // global, cause i need to pull string from void method
public static double GlobalLatitude = 0.0;
static readonly string TAG = "X:" + typeof(Activity1).Name;
Location _currentLocation;
LocationManager _locationManager;
string _locationProvider;
TextView _locationText;
static TextView txtAdded;
static Button btnMain;
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.Main);
_locationText = FindViewById<TextView>(Resource.Id.GpsTest);
txtAdded = FindViewById<TextView>(Resource.Id.AddedCoordinates);
btnMain = FindViewById<Button>(Resource.Id.startbutton);
CountDown();
InitializeLocationManager();
} // start here! :D
private void CountDown()
{
System.Timers.Timer timer = new System.Timers.Timer();
timer.Interval = 5000;
timer.Elapsed += OnTimedEvent;
timer.Enabled = true;
}
private void OnTimedEvent(object sender, System.Timers.ElapsedEventArgs e) // txt.Added is here!
{
txtAdded.Text = SetMockLocation();
}
public void OnLocationChanged(Location location)
{
string test = "Null";
string test2 = "Null";
bool waitforresult = false;
_currentLocation = location;
if (_currentLocation == null)
{
_locationText.Text = "Unable to determine your location. Try again in a short while.";
}
else
{
_locationText.Text = string.Format("Unchanged: {0:f5} {1:f5}", _currentLocation.Latitude, _currentLocation.Longitude);// hh: 53, 10
//das her wird ausgegeben bei button.click
test = string.Format("{0:f5}", _currentLocation.Latitude); // to format
test2 = string.Format("{0:f5}", _currentLocation.Longitude);
double.TryParse(test, out GlobalLatitude);
double.TryParse(test2, out GlobalLongitude);
if (test != "Null")
{
waitforresult = true;
}
if (waitforresult == true)
{
Add700ToCoordinates();
}
}
} // ausgabe der koordinaten
void InitializeLocationManager()
{
_locationManager = (LocationManager)GetSystemService(LocationService);
Criteria criteriaForLocationService = new Criteria
{
Accuracy = Accuracy.Fine
};
IList<string> acceptableLocationProviders = _locationManager.GetProviders(criteriaForLocationService, true);
if (acceptableLocationProviders.Any())
{
_locationProvider = acceptableLocationProviders.First();
}
else
{
_locationProvider = string.Empty;
}
Log.Debug(TAG, "Using " + _locationProvider + ".");
}
protected override void OnResume()
{
base.OnResume();
_locationManager.RequestLocationUpdates(_locationProvider, 0, 0, this);
Log.Debug(TAG, "Listening for location updates using " + _locationProvider + ".");
}
protected override void OnPause()
{
base.OnPause();
_locationManager.RemoveUpdates(this);
Log.Debug(TAG, "No longer listening for location updates.");
}
public static double Add700ToCoordinates()
{
string xy = "Null";
double FinalCoordinates = (GlobalLatitude + 0.01065);
btnMain.Click += (sender, e) =>
{
xy = FinalCoordinates.ToString();
xy = xy + " " + GlobalLongitude.ToString();
};
return FinalCoordinates;
}
public static string SetMockLocation()
{
var context = Android.App.Application.Context;
var locationManager = context.GetSystemService(LocationService) as LocationManager;
locationManager.AddTestProvider("Test09", false, false, false, false, false, false, false, Power.Low, Android.Hardware.SensorStatus.AccuracyHigh);
locationManager.SetTestProviderEnabled("Test09", true);
var location = new Location("Test09");
location.Latitude = Add700ToCoordinates();
location.Longitude = GlobalLongitude;
location.Accuracy = 0; // ob das geht?... ja, aber was beduetet es?
location.Time = DateTime.Now.Ticks;
location.ElapsedRealtimeNanos = 100; // hier das gleiche... was hießt es? :D
locationManager.SetTestProviderLocation("Test09", location);
//Check if your event reacted the right way
locationManager.RemoveTestProvider("Test09");
return location.Latitude.ToString();
}
}
}
There are probably two things at play here - service and background processing.
You can set the mock locations, probably, as a service that runs in the background. You can do this in the native code.
And if you are using Xamarin or Xamarin Forms you can utilize the MessagingCenter feature to talk/access the service.
You can have native code running services in the background and your PCL/shared code can access from native code information that you need.
You can check on this link for some very helpful example and walkthrough.
First you need to create native implementation for services for each platform.
For Android:
You need to wrap your service into Android Service to have capability work in background. Please see this references https://developer.android.com/guide/components/services.html
https://developer.xamarin.com/guides/android/application_fundamentals/services/
For iOS:
It's little beat harder. First read this reference, especially "Declaring Your App’s Supported Background Tasks" part.(https://developer.apple.com/library/content/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/BackgroundExecution/BackgroundExecution.html)
So you can use "Location updates" background mode and inject your mock-generator service into "locations updates" service.
Below example for xamarin iOS:
private void StartAccelerometerUpdates()
{
if (_motionManager.AccelerometerAvailable)
_motionManager.AccelerometerUpdateInterval = ACCEL_UPDATE_INTERVAL;
_motionManager.StartAccelerometerUpdates (NSOperationQueue.MainQueue, AccelerometerDataUpdatedHandler);
}
public void AccelerometerDataUpdatedHandler(CMAccelerometerData data, NSError error)
{ //your mock-generator code }
I'd like to share an image in my app. However, the image is not located in a folder but it is "taken dynamically". Basically i have an Image object
Image i = new Image() { Source = await CreateBitmapFromElement(stackpanel1) };
where CreateBitmapFromElement is defined as follows
private async Task<RenderTargetBitmap> CreateBitmapFromElement(FrameworkElement uielement)
{
try
{
var renderTargetBitmap = new RenderTargetBitmap();
await renderTargetBitmap.RenderAsync(uielement);
return renderTargetBitmap;
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex);
}
return null;
}
The Windows Phone Share Contract allows to share images located in the Picture Library (for example), but what should i use in this case?
protected override void OnNavigatedTo(NavigationEventArgs e)
{
DataTransferManager.GetForCurrentView().DataRequested += OnShareDataRequested;
base.OnNavigatedTo(e);
}
protected override void OnNavigatedFrom(NavigationEventArgs e)
{
DataTransferManager.GetForCurrentView().DataRequested -= OnShareDataRequested;
base.OnNavigatedFrom(e);
}
private void OnShareDataRequested(DataTransferManager sender, DataRequestedEventArgs _dataRequestedEventArgs)
{
DataRequest request = _dataRequestedEventArgs.Request;
request.Data.Properties.Title = "KeyTreat Sticker";
request.Data.Properties.Description = "KeyTreat Sticker: " + StickerName;
// Because we are making async calls in the DataRequested event handler,
// we need to get the deferral first.
DataRequestDeferral deferral = request.GetDeferral();
// Make sure we always call Complete on the deferral.
try
{
request.Data.SetStorageItems(storageItemsObject);
request.Data.Properties.Thumbnail = RandomAccessStreamReference.CreateFromFile(StorageFileObject);
request.Data.SetBitmap(RandomAccessStreamReference.CreateFromFile(StorageFileObject));
}
finally
{
deferral.Complete();
}
}
Trying to test my WP7 app that uses location following this tutorial.
I have additional tools open, start the emulator from VS, let the app launch and then I place a pin in Live-mode in the Additional Tools Location utility, but no event is fired.
Is there anything wrong with my code?
public MainPage()
{
InitializeComponent();
InitWatcher();
}
private void InitWatcher()
{
geoWatcher = new GeoCoordinateWatcher(GeoPositionAccuracy.High);
geoWatcher.PositionChanged += new EventHandler<GeoPositionChangedEventArgs<GeoCoordinate>>(geoWatcher_PositionChanged);
geoWatcher.StatusChanged += new EventHandler<GeoPositionStatusChangedEventArgs>(geoWatcher_StatusChanged);
}
private void geoWatcher_PositionChanged(object sender, GeoPositionChangedEventArgs<GeoCoordinate> e)
{
var lol = e;
}
private void geoWatcher_StatusChanged(object sender, GeoPositionStatusChangedEventArgs e)
{
var FK = e;
}
The problem is that you have to start the GeoCoordinateWatcher:
geoWatcher = new GeoCoordinateWatcher(GeoPositionAccuracy.High);
geoWatcher.PositionChanged += new EventHandler<GeoPositionChangedEventArgs<GeoCoordinate>>(geoWatcher_PositionChanged);
geoWatcher.StatusChanged += new EventHandler<GeoPositionStatusChangedEventArgs>(geoWatcher_StatusChanged);
geoWatcher.Start();
Do you need to call the Start method on your GeoCoordinateWatcher instance?
http://msdn.microsoft.com/en-us/library/ee808853.aspx
Is there a way to show "Loading" screen with animation in blackberry?
Options:
PME animation content
multithreading + set of images + timer/counter
standard rim api
some other way
Any of this?
Thanks!
Fermin, Anthony +1. Thanks to all, you gave me the part of answer.
My final solution:
1.Create or generate (free Ajax loading gif generator) animation and add it to project.
2.Create ResponseCallback interface (see Coderholic - Blackberry WebBitmapField) to receive thread execution result:
public interface ResponseCallback {
public void callback(String data);
}
3.Create a class to handle your background thread job. In my case it was http request:
public class HttpConnector
{
static public void HttpGetStream(final String fileToGet,
final ResponseCallback msgs) {
Thread t = new Thread(new Runnable() {
public void run() {
HttpConnection hc = null;
DataInputStream din = null;
try {
hc = (HttpConnection) Connector.open("http://" + fileToGet);
hc.setRequestMethod(HttpsConnection.GET);
din = hc.openDataInputStream();
ByteVector bv = new ByteVector();
int i = din.read();
while (-1 != i) {
bv.addElement((byte) i);
i = din.read();
}
final String response = new String(bv.toArray(), "UTF-8");
UiApplication.getUiApplication().invokeLater(
new Runnable() {
public void run() {
msgs.callback(response);
}
});
}
catch (final Exception e) {
UiApplication.getUiApplication().invokeLater(
new Runnable() {
public void run() {
msgs.callback("Exception (" + e.getClass() + "): "
+ e.getMessage());
}
});
}
finally {
try {
din.close();
din = null;
hc.close();
hc = null;
}
catch (Exception e) {
}
}
}
});
t.start();
}
}
4.Create WaitScreen (a hybrid of FullScreen and AnimatedGIFField with ResponseCallback interface):
public class WaitScreen extends FullScreen implements ResponseCallback
{
StartScreen startScreen;
private GIFEncodedImage _image;
private int _currentFrame;
private int _width, _height, _xPos, _yPos;
private AnimatorThread _animatorThread;
public WaitScreen(StartScreen startScreen) {
super(new VerticalFieldManager(), Field.NON_FOCUSABLE);
setBackground(
BackgroundFactory.createSolidTransparentBackground(
Color.WHITE, 100));
this.startScreen = startScreen;
EncodedImage encImg =
GIFEncodedImage.getEncodedImageResource("ajax-loader.gif");
GIFEncodedImage img = (GIFEncodedImage) encImg;
// Store the image and it's dimensions.
_image = img;
_width = img.getWidth();
_height = img.getHeight();
_xPos = (Display.getWidth() - _width) >> 1;
_yPos = (Display.getHeight() - _height) >> 1;
// Start the animation thread.
_animatorThread = new AnimatorThread(this);
_animatorThread.start();
UiApplication.getUiApplication().pushScreen(this);
}
protected void paint(Graphics graphics) {
super.paint(graphics);
// Draw the animation frame.
graphics
.drawImage(_xPos, _yPos, _image
.getFrameWidth(_currentFrame), _image
.getFrameHeight(_currentFrame), _image,
_currentFrame, 0, 0);
}
protected void onUndisplay() {
_animatorThread.stop();
}
private class AnimatorThread extends Thread {
private WaitScreen _theField;
private boolean _keepGoing = true;
private int _totalFrames, _loopCount, _totalLoops;
public AnimatorThread(WaitScreen _theScreen) {
_theField = _theScreen;
_totalFrames = _image.getFrameCount();
_totalLoops = _image.getIterations();
}
public synchronized void stop() {
_keepGoing = false;
}
public void run() {
while (_keepGoing) {
// Invalidate the field so that it is redrawn.
UiApplication.getUiApplication().invokeAndWait(
new Runnable() {
public void run() {
_theField.invalidate();
}
});
try {
// Sleep for the current frame delay before
// the next frame is drawn.
sleep(_image.getFrameDelay(_currentFrame) * 10);
} catch (InterruptedException iex) {
} // Couldn't sleep.
// Increment the frame.
++_currentFrame;
if (_currentFrame == _totalFrames) {
// Reset back to frame 0
// if we have reached the end.
_currentFrame = 0;
++_loopCount;
// Check if the animation should continue.
if (_loopCount == _totalLoops) {
_keepGoing = false;
}
}
}
}
}
public void callback(String data) {
startScreen.updateScreen(data);
UiApplication.getUiApplication().popScreen(this);
}
}
5.In the end, create Start screen to call HttpConnector.HttpGetStream and to show WaitScreen:
public class StartScreen extends MainScreen
{
public RichTextField text;
WaitScreen msgs;
public StartScreen() {
text = new RichTextField();
this.add(text);
}
protected void makeMenu(Menu menu, int instance) {
menu.add(runWait);
super.makeMenu(menu, instance);
}
MenuItem runWait = new MenuItem("wait", 1, 1) {
public void run() {
UiApplication.getUiApplication().invokeLater(
new Runnable() {
public void run() {
getFile();
}
});
}
};
public void getFile() {
msgs = new WaitScreen(this);
HttpConnector.HttpGetStream(
"stackoverflow.com/faq", msgs);
}
//you should implement this method to use callback data on the screen.
public void updateScreen(String data)
{
text.setText(data);
}
}
UPDATE: another solution naviina.eu: A Web2.0/Ajax-style loading popup in a native BlackBerry application
The basic pattern for this kind of thing is:
Have a thread running a loop that updates a variable (such as the frame index of the animated image) and then calls invalidate on a Field which draws the image (and then sleeps for a period of time). The invalidate will queue a repaint of the field.
In the field's paint method, read the variable and draw the appropriate frame of the image.
Pseudo code (not totally complete, but to give you the idea):
public class AnimatedImageField extends Field implements Runnable {
private int currentFrame;
private Bitmap[] animationFrames;
public void run() {
while(true) {
currentFrame = (currentFrame + 1) % animationFrames.length;
invalidate();
Thread.sleep(100);
}
}
protected void paint(Graphics g) {
g.drawBitmap(0, 0, imageWidth, imageHeight, animationFrames[currentFrame], 0, 0);
}
}
Note also here I used an array of Bitmaps, but EncodedImage lets you treat an animated gif as one object, and includes methods to get specific frames.
EDIT: For completeness: Add this to a PopupScreen (as in Fermin's answer) or create your own dialog by overriding Screen directly. The separate thread is necessary because the RIM API is not thread-safe: you need to do everything UI related on the event thread (or while holding the event lock, see BlackBerry UI Threading - The Very Basics
This is simple code for loading screen ....
HorizontalFieldManager popHF = new HorizontalFieldManager();
popHF.add(new CustomLabelField("Pls wait..."));
final PopupScreen waitScreen = new PopupScreen(popHF);
new Thread()
{
public void run()
{
synchronized (UiApplication.getEventLock())
{
UiApplication.getUiApplication().pushScreen(waitScreen);
}
//Here Some Network Call
synchronized (UiApplication.getEventLock())
{
UiApplication.getUiApplication().popScreen(waitScreen);
}
}
}.start();
If it's just an animation could you show an animated gif on a popup and close it when loading operation is complete?
Easiest way is probably to use the standard GaugeField, setting style GaugeField.PERCENT. This will give you a progress bar. Add this to a PopupScreen and it will sit on top of your content. Something like..
private GaugeField _gaugeField;
private PopupScreen _popup;
public ProgressBar() {
DialogFieldManager manager = new DialogFieldManager();
_popup = new PopupScreen(manager);
_gaugeField = new GaugeField(null, 0, 100, 0, GaugeField.PERCENT);
manager.addCustomField(_gaugeField);
}
Then have an update method which will use _gaugeField.setValue(newValue); to update the progress bar.
I normally have this called from whichever thread is doing the work (loading in your case, everytime an operation is complete the progress bar is updated.
I would suggest to take a look at this simple implementation. I liked this but never used it. May be helpful to you.
link text
ActivityIndicator is a good option if you are working with at least BB OS 6.0.
http://www.brighthub.com/mobile/blackberry-platform/articles/94258.aspx
http://docs.blackberry.com/en/developers/deliverables/17966/Screen_APIs_1245069_11.jsp