How to reset time for data logging in micro:bit micropython - micropython

I would like to start data logging in a bbc micro:bit with the press of its button_a, in order to be able to synchronize the timestamps with an external clock.
The idea is that, if I press the button at 12:10 o'clock, I would know that the first row of data (with 0.00 timestamp) was taken at that time (+/- human reaction time, of course).
The problem is that the zero time of the timestamps begin when the bbc micro:bit is turn on (or reset); so the first timestamp in the log file is not 0.00.
Of course, I could synchronize with that turning-on, but I think it would not be that accurate (I'm using the micro:bit with a robotbit board, which has a big 'on-off' switch.)
What I would like would be some kind of reset_time() method. :)
The code is this:
from microbit import *
import log
log.set_labels('altitude', 'azimuth', 'measure', timestamp=log.SECONDS)
# Wait until Button 'A' is pressed. This way, we can sinchronize the measures with an external clock or watch
while not button_a.was_pressed():
pass
for altitude in...
for azimuth in...
measure=take_reading()
log.add({
'altitude': altitude,
'azimuth': azimuth,
'measure': measure
})
The full code is here: https://github.com/lopezsolerluis/foto-teodolito-log

Related

microbit why blinking leds is so slow?

Using this basic example code from microbit, blinking heart, I tried to change the delay of blinking with the pause argument. However, the minimum actual blinking frequency is around 500ms, no matter what value i put.
Do you know why, and how I can achieve much faster blinking with led patterns (like show_icon or show_leds function).
def on_forever():
basic.show_icon(IconNames.HEART)
basic.pause(50)
basic.show_icon(IconNames.SMALL_HEART)
basic.pause(50)
basic.forever(on_forever)
Thanks.
You have tagged this as micropython but I don't believe that is what you are using. I think you are running with the Python in the MakeCode editor.
Looking at the help page for for the MakeCode show_icon, it says it is called with:
def basic.show_icon(icon: IconNames, interval: null): None
with the following details about interval:
interval (optional), the time to display in milliseconds. default is
600.
As you were not putting a value for interval it was defaulting to 600 milliseconds which meant your code was putting 650 milliseconds delay between each icon.
I was able to vary the duration an icon was displayed with the following:
def on_forever():
basic.show_icon(IconNames.HEART, 100)
basic.show_icon(IconNames.SMALL_HEART, 400)
basic.show_icon(IconNames.HEART, 100)
basic.show_icon(IconNames.SMALL_HEART, 800)
basic.forever(on_forever)

How to get the current time during the simulation

I would like to display the current time during my simulation so that I can simulate with full screen and also have the time. I tried the function getMinute(Date date) and a variable date. I didn't get an error but I also didn't get the time. Is it also possible to have a clock which displays the time?
You can do this:
String.format("%02d:%02d",getHourOfDay(), getMinute())
This will give you a string with the current time during the simulation
You can also use the clock object in the pictures palette to display time
you can use date() to know the date and time

How do I use system time as a trigger in codesys ladder?

Programming a raspberry pi with codesys, using mostly ladder, basically I need to write all data that is currently in a couple arrays to a csv file at midnight, so i'd like to be able to use a dt value as a trigger. I can't figure out how to use that value in ladder, however. I can display the local time on visualizer, but if i wanted something like "if localTime=#value" then coil 'Write' turns on, where is the actual variable for system time?
As far as I know, you need to read the clock from local system using function blocks, for example GetDateAndTime from CAA DTUtil Extern Library. Then you need to keep it up-to-date by using a function block, for example RTC from Standard libary
The following reads the system local time and then updates it with a RTC function block. Works at least on Windows, couldn't test with Raspberry. Please note that if the local time changes for some reason, this won't update it again. So you need to run the GetDateAndTime call every now and then, for example.
First, a program that updates and provides the local time:
PROGRAM PRG_UpdateSystemTime
VAR_OUTPUT
SystemDateTime : DT;
END_VAR
VAR
ReadLocalTime : DTU.GetDateAndTime; //Reads local time from system
RtcBlock : RTC; //Real-time clock - updates the previously received local time
END_VAR
//NOTE: Output is UTC time
//The block that reads local time. NOTE: Error handling is missing
ReadLocalTime(xExecute:= TRUE);
//Running real-time clock
RtcBlock(
EN := ReadLocalTime.xDone AND NOT ReadLocalTime.xError,
PDT := ReadLocalTime.dtDateAndTime,
CDT => SystemDateTime
);
And then one example for ladder. I think there are millions of ways. Note that the "DoSomething" will be TRUE for the whole second, so you should probably use rising edge detection.

How can I save output from Simulink?

I'm a student learning to use MATLAB. For an assignment, I have to create a simple state machine and collect some results. I'm used to using Verilog/Modelsim, and I'd like to collect data only when the state machine's output changes, which is not necessarily every time/sample period.
Right now I have a model that looks like this:
RequestChart ----> ResponseChart ----> Unit Delay Block --> (Back to RequestChart)
| |
------------------------> Mux --> "To Workspace" Sink Block
I've tried setting the sink block to save as "Array" format, but it only saves 51 values. I've tried setting it to "Timeseries", but it saves tons of zero values.
Can someone give me some suggestions? Like I said, MATLAB is new to me, please let me know if I need to clarify my question or provide more information.
Edit: Here's a screen capture of my model:
Generally Simulink will output a sample at every integration step. If you want to only output data when a particular event occurs -- in this case only when some data changes -- then do the following,
run the output of the state machine into a Detect Change block (from the Logic and Bit Operations library)
run that signal into the trigger port of a Triggered Subsystem.
run the output of the state machine into the data port of the Triggered Subsystem.
inside the triggered subsystem, run the data signal into a To Workspace block.
Data will only be saved at time point that the trigger occurs, i.e. when your data changes.
In your Simulink window, make sure the Relative Tolerance is small so that you can generate many more points in between your start and ending time. Click on the Simulation option at the top of the window, then click on Model Configuration Parameters.
From there, change the Relative Tolerance to something small... like 1e-10. After that, try running your simulation again. You should have a lot more points in your output array that you can now save.

Is it possible to get the atomic clock timestamp from the iphone GPS?

I'm looking for a reliable way to get the time. It can't be tampered with and it needs to work offline. So no internet time , no user time setup in settings and no BSD uptime time since last reboot. I was wondering since GPS works using atomic clock, whether I could access that information.
Thank you
This works to get the GPS time:
#import <CoreLocation/CoreLocation.h>
CLLocation* gps = [[CLLocation alloc]
initWithLatitude:(CLLocationDegrees) 0.0
longitude:(CLLocationDegrees) 0.0];
NSDate* now = gps.timestamp;
It doesn't seem to be tamper-proof though.
I tried this code on an iPhone 4 in airplane mode (iOS 6.1), and even then it gives a time all right. But unfortunately this time seems to change with the system clock. Ugh.
Funny thing that I found (still in airplane mode) is that if you tamper with the system clock (after turning to off Time & Date's Set Automatically), and then turn Set Automatically back to on, the machine restores the real (original) time without a hitch. this works even after cycling the phone's power. So it seems that there is something like a tamper-proof time the device maintains internally. But how to access this?
P.S. A discussion of this from 2010. The author of the penultimate comment tried this in a fallout shelter: so it's clear the phone is not getting the pristine time from any external source.
Addendum, July 2013
Found a few more posts (here, here and here) about another kind of time measure: system kernel boot time. It's accessed through a call something like this: sysctlbyname("kern.boottime", &boottime, &size, NULL, 0);. Unfortunately it too changes with the user-adjusted data and time, even without reboot. Another function gettimeofday() is similarly dependent on user-defined time.
NSDate and it's CF counterpart are all based on the user controllable time, and thereby aren't tamper proof.
As far as I know, there is no open API for either GPS time or carrier time directly. However, you can check the mach_absolute_time to get untampered time since last boot up, and perhaps use it to at least be aware of how much time has passed since the app has been awoken (without having the potential for that time to be tampered with while the app is running).
mach_absolute_time depends on the processor of the device. It returns ticks since the device was last rebooted (otherwise known as uptime). In order to get it in a human readable form, you have to modify it by the result from mach_timebase_info (a ratio), which will return billionth of seconds (or nanoseconds). To make this more usable I use a function like the one below:
#include <mach/mach_time.h>
int getUptimeInMilliseconds()
{
static const int64_t kOneMillion = 1000 * 1000;
static mach_timebase_info_data_t s_timebase_info;
if (s_timebase_info.denom == 0) {
(void) mach_timebase_info(&s_timebase_info);
}
// mach_absolute_time() returns billionth of seconds,
// so divide by one million to get milliseconds
return (int)((mach_absolute_time() * s_timebase_info.numer) / (kOneMillion * s_timebase_info.denom));
}
Even if you can get hold of the time from GPS you should be aware that GPS time is not quite the same as UTC. The GPS receiver in the iPhone might take care of that for you though.
This gets you the current date and time:
NSDate *now = [NSDate date];
This will be as reliable as you can get. The internal clock on the iPhone will be updated when it can get access to an NTP server. If the phone uses GPS as a time sync source it'll also be used to update the same system-wide clock which is accessible via the above method.
The CoreFoundation equivalent is something like:
CFAbsoluteTime now = CFAbsoluteTimeGetCurrent();
Which returns the CoreFoundation equivalent of the normal UNIX seconds-since-epoch timestamp.
The gold standard of timekeeping are the various government time observatories in the U.S. and worldwide. They provide Atomic time. That is used world wide. Apple should be using that. If the want to sync w/ the cell towers, there should be an Alternate internal time. If the tower or GPS system malfunctions all are left with incorrect time.