Skip to content

Instantly share code, notes, and snippets.

@Adrenocortico
Created April 11, 2016 17:45
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Adrenocortico/38562e84369f56531e8b05f5de88c9b8 to your computer and use it in GitHub Desktop.
Save Adrenocortico/38562e84369f56531e8b05f5de88c9b8 to your computer and use it in GitHub Desktop.
DeviceDetailViewController
#import <UIKit/UIKit.h>
#import <MetaWear/MetaWear.h>
#import <MessageUI/MessageUI.h>
#import <MessageUI/MFMailComposeViewController.h>
@interface DeviceDetailViewController : UIViewController {
NSTimer *timer;
double countInt;
}
@property (strong, nonatomic) MBLMetaWear *device;
@end
#import "DeviceDetailViewController.h"
#import "MBProgressHUD.h"
#import "APLGraphView.h"
@interface DeviceDetailViewController () <MFMailComposeViewControllerDelegate>
@property (weak, nonatomic) IBOutlet UIScrollView *scrollView;
@property (weak, nonatomic) IBOutlet UISwitch *connectionSwitch;
@property (weak, nonatomic) IBOutlet UILabel *batteryLevelLabel;
@property (weak, nonatomic) IBOutlet UIButton *beautyButton;
@property (weak, nonatomic) IBOutlet UIButton *stopMeNow;
@property (strong, nonatomic) UIView *grayScreen;
@property (strong, nonatomic) NSArray *accelerometerDataArray;
@property (nonatomic) int tapCount;
@property (nonatomic, strong) NSMutableArray *streamingEvents;
@property (nonatomic) BOOL switchRunning;
@property (nonatomic) BOOL isObserving;
@property (nonatomic, strong) UIDocumentInteractionController *controller;
@end
@implementation DeviceDetailViewController
- (void)viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
// Use this array to keep track of all streaming events, so turn them off in case the user isn't so responsible
self.streamingEvents = [NSMutableArray array];
self.isObserving = YES;
// Start off the connection flow
[self connectDevice:YES];
}
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
self.isObserving = NO;
for (MBLEvent *event in self.streamingEvents) {
[event stopNotificationsAsync];
}
[self.streamingEvents removeAllObjects];
}
- (void)setIsObserving:(BOOL)isObserving
{
@synchronized(self) {
if (isObserving) {
if (_isObserving) {
// Do nothing
} else {
[self.device addObserver:self forKeyPath:@"state" options:NSKeyValueObservingOptionNew context:nil];
}
} else {
if (_isObserving) {
[self.device removeObserver:self forKeyPath:@"state"];
} else {
// Do nothing
}
}
_isObserving = isObserving;
}
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
if (self.device.state == CBPeripheralStateDisconnected) {
[self deviceDisconnected];
// [self.scrollView scrollRectToVisible:CGRectMake(0, 0, 10, 10) animated:YES];
}
}];
}
- (void)logCleanup:(MBLErrorHandler)handler
{
// In order for the device to actaully erase the flash memory we can't be in a connection so temporally disconnect to allow flash to erase.
self.isObserving = NO;
[self.device disconnectWithHandler:^(NSError *error) {
self.isObserving = YES;
if (error) {
if (handler) {
handler(error);
}
} else {
[self.device connectWithTimeout:15 handler:^(NSError *error) {
if (handler) {
handler(error);
}
}];
}
}];
}
- (void)showAlertTitle:(NSString *)title message:(NSString *)message
{
[[[UIAlertView alloc] initWithTitle:title
message:message
delegate:nil
cancelButtonTitle:@"Ok"
otherButtonTitles:nil] show];
}
- (void)deviceDisconnected
{
[self.connectionSwitch setOn:NO animated:YES];
}
- (void)deviceConnected {
[self.connectionSwitch setOn:YES animated:YES];
NSLog(@"ID: %@", self.device.identifier.UUIDString);
[self.grayScreen setHidden:YES];
}
- (void)connectDevice:(BOOL)on
{
MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:[UIApplication sharedApplication].keyWindow animated:YES];
if (on) {
hud.labelText = NSLocalizedString(@"Connection", "detailConnection");
[self.device connectWithTimeout:15 handler:^(NSError *error) {
if ([error.domain isEqualToString:kMBLErrorDomain] && error.code == kMBLErrorOutdatedFirmware) {
[hud hide:YES];
[self updateDevice:nil];
return;
}
hud.mode = MBProgressHUDModeText;
if (error) {
[self showAlertTitle:NSLocalizedString(@"Error", "detailErrorConnection") message:error.localizedDescription];
[hud hide:NO];
} else {
[self deviceConnected];
hud.labelText = NSLocalizedString(@"Connected", "detailConnected");
[hud hide:YES afterDelay:0.5];
}
}];
} else {
hud.labelText = NSLocalizedString(@"Disconnection", "detailDisconnetion");
[self.device disconnectWithHandler:^(NSError *error) {
[self deviceDisconnected];
hud.mode = MBProgressHUDModeText;
if (error) {
[self showAlertTitle:NSLocalizedString(@"Error", "detailErrorDisconnection") message:error.localizedDescription];
[hud hide:NO];
} else {
hud.labelText = NSLocalizedString(@"Disconnected", "detailDisconnected");
[hud hide:YES afterDelay:0.5];
}
}];
}
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.grayScreen = [[UIView alloc] initWithFrame:CGRectMake(0, 120, self.view.frame.size.width, self.view.frame.size.height - 120)];
self.grayScreen.backgroundColor = [UIColor grayColor];
self.grayScreen.alpha = 0.4;
[self.view addSubview:self.grayScreen];
}
- (IBAction)connectionSwitchPressed:(id)sender
{
[self connectDevice:self.connectionSwitch.on];
}
- (IBAction)readBatteryPressed:(id)sender
{
[self.device readBatteryLifeWithHandler:^(NSNumber *number, NSError *error) {
self.batteryLevelLabel.text = [number stringValue];
}];
}
- (IBAction)resetDevicePressed:(id)sender
{
// Resetting causes a disconnection
[self deviceDisconnected];
// Preform the soft reset
[self.device resetDevice];
}
- (void)updateFirmware {
// Pause the screen while update is going on
MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:[UIApplication sharedApplication].keyWindow animated:YES];
hud.mode = MBProgressHUDModeDeterminateHorizontalBar;
hud.labelText = NSLocalizedString(@"Updating", "detailUpdating");
[self.device updateFirmwareWithHandler:^(NSError *error) {
hud.mode = MBProgressHUDModeText;
if (error) {
NSLog(@"Errore update firmware: %@", error.localizedDescription);
[self showAlertTitle:NSLocalizedString(@"Update error", "detailUpdateErrorTitle") message:[NSLocalizedString(@"Please, reconnect and try again.\nError: ", "detailUpdateErrorMess") stringByAppendingString:error.localizedDescription]];
[hud hide:YES];
} else {
hud.labelText = NSLocalizedString(@"Success", "detailUpdatingSuccess");
[hud hide:YES afterDelay:2.0];
}
} progressHandler:^(float number) {
hud.progress = number;
if (number == 1.0) {
hud.mode = MBProgressHUDModeIndeterminate;
hud.labelText = NSLocalizedString(@"Resetting", "detailUpdatingResetting");
}
}];
}
- (IBAction)updateDevice:(id)sender
{
[self updateFirmware];
}
#pragma mark - Settings
- (void)setAccelerometer
{
MBLAccelerometerMMA8452Q *accelerometerMMA8452Q = (MBLAccelerometerMMA8452Q *)self.device.accelerometer;
accelerometerMMA8452Q.fullScaleRange = 1;
accelerometerMMA8452Q.sampleFrequency = 7; // 7 Hz = 142 ms
accelerometerMMA8452Q.highPassFilter = false;
//self.device.accelerometer.filterCutoffFreq = 0;
accelerometerMMA8452Q.lowNoise = false;
accelerometerMMA8452Q.activePowerScheme = 0;
accelerometerMMA8452Q.autoSleep = false;
accelerometerMMA8452Q.sleepSampleFrequency = 0;
accelerometerMMA8452Q.sleepPowerScheme = 0;
accelerometerMMA8452Q.tapDetectionAxis = 2;
accelerometerMMA8452Q.tapType = 0;
countInt = 0;
}
-(void)countTimer {
countInt += 0.5;
}
- (void)startMeNow {
[self setAccelerometer];
// Timer
timer = [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(countTimer) userInfo:nil repeats:YES];
// These variables are used for data recording
NSMutableArray *array = [[NSMutableArray alloc] initWithCapacity:1000];
self.accelerometerDataArray = array;
[self.streamingEvents addObject:self.device.accelerometer.dataReadyEvent];
[self.device.accelerometer.dataReadyEvent startNotificationsWithHandlerAsync:^(MBLAccelerometerData * _Nullable acceleration, NSError * _Nullable error) {
if (acceleration) {
double x = acceleration.x / 1000.0;
double y = acceleration.y / 1000.0;
double z = acceleration.z / 1000.0;
double rho = atan2(z, -y) * 180 / M_PI;
double phi = atan2(x, z) * 180 / M_PI;
int dphi = floor(phi);
int drho = floor(rho);
// Add data to data array for saving
[array addObject:acceleration];
uint8_t delay = 1.5;
uint8_t pretty = 34;
uint8_t beautyAngle = 75;
uint8_t uglyAngle = 45;
if (dphi < (beautyAngle - pretty + 2) && countInt >= delay) {
[self.device.hapticBuzzer startHapticWithDutyCycleAsync:248 pulseWidth:350 completion:nil];
countInt = 0;
};
if (dphi > (uglyAngle + pretty + 2) && countInt >= delay) {
[self.device.hapticBuzzer startHapticWithDutyCycleAsync:248 pulseWidth:350 completion:nil];
countInt = 0;
};
}
}];
}
-(void)StopMeNow {
[self.streamingEvents removeObject:self.device.accelerometer.dataReadyEvent];
[self.device.accelerometer.dataReadyEvent stopNotificationsAsync];
}
- (IBAction)sedutoPressed:(id)sender
{
[self.beautyButton setEnabled:NO];
[self.StopMeNow setEnabled:YES];
[self startMeNow];
}
- (IBAction)StopMeNowPressed:(id)sender
{
[self.StopMeNow setEnabled:NO];
[self.calibraButton setHidden:NO];
[self.calibraButton setEnabled:YES];
[self.beautyButton setEnabled:YES];
[self.inpiediButton setEnabled:YES];
[self StopMeNow];
[timer invalidate];
countInt = 0;
}
@end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment