Compare commits

..

2 Commits

Author SHA1 Message Date
e0aad7227f Add file listing and delete apis 2019-09-03 16:00:46 -07:00
aca1b4a764 Improve naming of command line programs 2019-09-03 16:00:33 -07:00
9 changed files with 98 additions and 222 deletions

Binary file not shown.

View File

@ -89,11 +89,18 @@ Sharing programs is also shown in the [Tips and Tricks](https://legoeducation.vi
### Why can't I delete my program (*.uf2) files from the Brick?
There's a bug in the firmware which prevents you from deleting the programs (``*.uf2`` files) from your EV3 Brick. There isn't a firmware update to fix this yet.
There's a bug in the firmware which prevents you from deleting the programs (``*.uf2`` files) from your EV3 Brick. There isn't a firmware update to fix this yet. As a workaround, you can temporarily downgrade your firmware version, delete the files, and then upgrade back to the version that works with MakeCode.
We have prepared a special program that lets you delete UF2 files from the brick.
Download [these PDF instructions](/file-manager.pdf) and drop the PDF on the brick drive.
This will present you with an menu for deleting files.
Follow these steps to downgrade your firmware version, delete the files, and uprgade back again:
1. Go into **EV3 LabVIEW** - if it's not installed get it [here](https://education.lego.com/en-us/downloads/mindstorms-ev3/software)
2. Plug in your EV3 Brick and start a new project
3. Go to the **Tools** menu in the upper right corner, select **Firmware Update**
4. In the **Firmware Update** dialog box, click on the **Show Details** button
5. From the **Available Firmware Files** list, select **EV3 Firmware V1.09E**
6. Click the **Update Firmware** button and wait for the update to complete
Now the firmware version on the EV3 Brick will be **V1.09E**. Also, in the process, the downgrade deleted all of the saved programs from the EV3 Brick. To continue to use MakeCode, the firmware version must be at **V1.10E** or above. So, the Brick firmware needs to be upgraded again. If you don't know or do remember how to do this, see the **Upgrade your @drivename@** section in the [troubleshooting](/troubleshoot) page.
For other common questions, try the FAQ page https://makecode.mindstorms.com/faq.

View File

@ -1,47 +0,0 @@
# battery Property
Return the information about the battery
```sig
brick.batteryInfo(BatteryProperty.Level)
```
## Parameters
* property: the kind of information
## Returns
* a [number](/types/number) which represents the value of the property requested.
## Example
Show the battery level percentage on the screen. Also, show a green light if the battery level is above 15%. If the battery level is below 15% but above 5%, show a orange light. But, if the battery level is below 5%, show a pulsing red light.
```blocks
let battery = 0;
forever(function() {
brick.showString("Battery level:", 1)
brick.showNumber(battery, 2)
battery = brick.batteryInfo(BatteryProperty.Level);
if (battery > 15)
{
brick.setStatusLight(StatusLight.Green);
} else if (battery > 5) {
brick.setStatusLight(StatusLight.Orange);
} else {
brick.setStatusLight(StatusLight.RedPulse)
}
pause(30000)
})
```
Or see all the values
```blocks
forever(function () {
brick.showValue("bat V", brick.batteryInfo(BatteryProperty.Voltage), 1)
brick.showValue("bat %", brick.batteryInfo(BatteryProperty.Level), 2)
brick.showValue("bat I", brick.batteryInfo(BatteryProperty.Current), 3)
})
```

View File

@ -63,7 +63,9 @@ const rbfTemplate = `
export function deployCoreAsync(resp: pxtc.CompileResult) {
let w: pxt.editor.Ev3Wrapper
let filename = resp.downloadFileBaseName || "pxt"
const origElfUF2 = UF2.parseFile(pxt.U.stringToUint8Array(ts.pxtc.decodeBase64(resp.outfiles[pxt.outputName()])))
let filename = resp.downloadFileBaseName || (origElfUF2[0].filename || "").replace(/^Projects\//, "").replace(/\.elf$/, "") || "pxt"
filename = filename.replace(/^lego-/, "")
let fspath = "../prjs/BrkProg_SAVE/"
@ -77,8 +79,6 @@ export function deployCoreAsync(resp: pxtc.CompileResult) {
let rbfBIN = pxt.U.fromHex(rbfHex)
pxt.HF2.write16(rbfBIN, 4, rbfBIN.length)
let origElfUF2 = UF2.parseFile(pxt.U.stringToUint8Array(ts.pxtc.decodeBase64(resp.outfiles[pxt.outputName()])))
let mkFile = (ext: string, data: Uint8Array = null) => {
let f = UF2.newBlockFile()
f.filename = "Projects/" + filename + ext

View File

@ -1,40 +1,13 @@
const enum BatteryProperty {
//% level (%)
Level,
//% block="current (I)"
Current,
//% block="voltage (V)"
Voltage
}
namespace brick {
/**
* Returns the current battery level
*/
//% blockId=brickBatteryLevel block="battery level"
//% group="Battery"
//% group="More"
//% help=brick/battery-level
//% deprecated blockHidden=1
export function batteryLevel(): number {
const info = sensors.internal.getBatteryInfo();
return info.level;
}
/**
* Returns information about the battery
*/
//% blockId=brickBatteryProperty block="battery %property"
//% group="Battery"
//% help=brick/battery-property
export function batteryInfo(property: BatteryProperty): number {
const info = sensors.internal.getBatteryInfo();
switch(property) {
case BatteryProperty.Level: return info.level;
case BatteryProperty.Current: return info.Ibatt;
case BatteryProperty.Voltage: return info.Vbatt;
default: return 0;
}
return info.current;
}
}

View File

@ -36,17 +36,8 @@ namespace sensors.internal {
let analogMM: MMap
let uartMM: MMap
let IICMM: MMap
let powerMM: MMap
let devcon: Buffer
let sensorInfos: SensorInfo[];
let batteryInfo: {
CinCnt: number;
CoutCnt: number;
VinCnt: number;
};
let batteryVMin: number;
let batteryVMax: number;
let sensorInfos: SensorInfo[]
class SensorInfo {
port: number
@ -80,13 +71,10 @@ namespace sensors.internal {
IICMM = control.mmap("/dev/lms_iic", IICOff.Size, 0)
if (!IICMM) control.fail("no iic sensor")
powerMM = control.mmap("/dev/lms_power", 2, 0)
unsafePollForChanges(500,
() => { return hashDevices(); },
(prev, curr) => {
detectDevices();
});
unsafePollForChanges(500,
() => { return hashDevices(); },
(prev, curr) => { detectDevices();
});
sensorInfos.forEach(info => {
unsafePollForChanges(50, () => {
if (info.sensor) return info.sensor._query()
@ -94,8 +82,9 @@ namespace sensors.internal {
}, (prev, curr) => {
if (info.sensor) info.sensor._update(prev, curr)
})
})
}
})
}
export function getActiveSensors(): Sensor[] {
init();
@ -121,130 +110,18 @@ namespace sensors.internal {
return manufacturer + sensorType;
}
const ADC_REF = 5000 //!< [mV] maximal value on ADC
const ADC_RES = 4095 //!< [CNT] maximal count on ADC
// see c_ui.c
const SHUNT_IN = 0.11 // [Ohm]
const AMP_CIN = 22.0 // [Times]
const EP2_SHUNT_IN = 0.05 // [Ohm]
const EP2_AMP_CIN = 15.0 // [Times]
const SHUNT_OUT = 0.055 // [Ohm]
const AMP_COUT = 19.0 // [Times]
const VCE = 0.05 // [V]
const AMP_VIN = 0.5 // [Times]
const AVR_CIN = 300
const AVR_COUT = 30
const AVR_VIN = 30
// lms2012
const BATT_INDICATOR_HIGH = 7500 //!< Battery indicator high [mV]
const BATT_INDICATOR_LOW = 6200 //!< Battery indicator low [mV]
const ACCU_INDICATOR_HIGH = 7500 //!< Rechargeable battery indicator high [mV]
const ACCU_INDICATOR_LOW = 7100 //!< Rechargeable battery indicator low [mV]
function CNT_V(C: number) {
return ((C * ADC_REF) / (ADC_RES * 1000.0))
}
function updateBatteryInfo() {
let CinCnt = analogMM.getNumber(NumberFormat.Int16LE, AnalogOff.BatteryCurrent);
let CoutCnt = analogMM.getNumber(NumberFormat.Int16LE, AnalogOff.MotorCurrent);
let VinCnt = analogMM.getNumber(NumberFormat.Int16LE, AnalogOff.Cell123456);
if (!batteryInfo) {
batteryVMin = BATT_INDICATOR_LOW;
batteryVMax = BATT_INDICATOR_HIGH;
if (powerMM) {
const accu = powerMM.getNumber(NumberFormat.UInt8LE, 0);
if (accu > 0) {
control.dmesg("rechargeable battery")
batteryVMin = ACCU_INDICATOR_LOW;
batteryVMax = ACCU_INDICATOR_HIGH;
}
}
batteryInfo = {
CinCnt: CinCnt,
CoutCnt: CoutCnt,
VinCnt: VinCnt
};
// update in background
control.runInParallel(() => forever(updateBatteryInfo));
} else {
CinCnt = batteryInfo.CinCnt = ((batteryInfo.CinCnt * (AVR_CIN - 1)) + CinCnt) / AVR_CIN;
CoutCnt = batteryInfo.CoutCnt = ((batteryInfo.CoutCnt * (AVR_COUT - 1)) + CoutCnt) / AVR_COUT;
VinCnt = batteryInfo.VinCnt = ((batteryInfo.VinCnt * (AVR_VIN - 1)) + VinCnt) / AVR_VIN;
}
}
export function getBatteryInfo(): {
level: number;
Ibatt: number,
Vbatt: number,
Imotor: number
} {
export function getBatteryInfo(): { temp: number; current: number } {
init();
if (!batteryInfo) updateBatteryInfo();
const CinCnt = batteryInfo.CinCnt;
const CoutCnt = batteryInfo.CoutCnt;
const VinCnt = batteryInfo.VinCnt;
/*
void cUiUpdatePower(void)
{
#ifndef Linux_X86
DATAF CinV;
DATAF CoutV;
if ((UiInstance.Hw == FINAL) || (UiInstance.Hw == FINALB))
{
CinV = CNT_V(UiInstance.CinCnt) / AMP_CIN;
UiInstance.Vbatt = (CNT_V(UiInstance.VinCnt) / AMP_VIN) + CinV + VCE;
UiInstance.Ibatt = CinV / SHUNT_IN;
CoutV = CNT_V(UiInstance.CoutCnt) / AMP_COUT;
UiInstance.Imotor = CoutV / SHUNT_OUT;
}
else
{
CinV = CNT_V(UiInstance.CinCnt) / EP2_AMP_CIN;
UiInstance.Vbatt = (CNT_V(UiInstance.VinCnt) / AMP_VIN) + CinV + VCE;
UiInstance.Ibatt = CinV / EP2_SHUNT_IN;
UiInstance.Imotor = 0;
}
#endif
#ifdef DEBUG_TEMP_SHUTDOWN
UiInstance.Vbatt = 7.0;
UiInstance.Ibatt = 5.0;
#endif
}
*/
const CinV = CNT_V(CinCnt) / AMP_CIN;
const Vbatt = CNT_V(VinCnt) / AMP_VIN + CinV + VCE;
const Ibatt = CinV / SHUNT_IN;
const CoutV = CNT_V(CoutCnt) / AMP_COUT;
const Imotor = CoutV / SHUNT_OUT;
const level = Math.max(0, Math.min(100, Math.floor((Vbatt * 1000.0 - batteryVMin)
/ (batteryVMax - batteryVMin) * 100)));
return {
level: level,
Vbatt: Vbatt,
Ibatt: Ibatt,
Imotor: Imotor
};
temp: analogMM.getNumber(NumberFormat.Int16LE, AnalogOff.BatteryTemp),
current: Math.round(analogMM.getNumber(NumberFormat.Int16LE, AnalogOff.BatteryCurrent) / 10)
}
}
function hashDevices(): number {
const conns = analogMM.slice(AnalogOff.InConn, DAL.NUM_INPUTS)
let r = 0;
for (let i = 0; i < conns.length; ++i) {
for(let i = 0; i < conns.length; ++i) {
r = (r << 8 | conns[i]);
}
return r;

View File

@ -23,6 +23,10 @@
#define MALLOC_LIMIT (8 * 1024 * 1024)
#define MALLOC_CHECK_PERIOD (1024 * 1024)
namespace Array_ {
RefCollection *mk(unsigned flags);
}
void *xmalloc(size_t sz) {
static size_t allocBytes = 0;
allocBytes += sz;
@ -476,7 +480,7 @@ void stopLMS() {
if (!pid)
continue;
char namebuf[100];
snprintf(namebuf, 1000, "/proc/%d/cmdline", pid);
snprintf(namebuf, 100, "/proc/%d/cmdline", pid);
FILE *f = fopen(namebuf, "r");
if (f) {
fread(namebuf, 1, 99, f);
@ -590,4 +594,66 @@ void dmesg(const char *format, ...) {
fflush(dmesgFile);
fdatasync(fileno(dmesgFile));
}
const char *progPath = "/mnt/ramdisk/prjs/BrkProg_SAVE";
//%
void deleteAllPrograms() {
char buf[1024];
struct dirent *ent;
DIR *dir;
dir = opendir(progPath);
if (dir == NULL)
return;
while ((ent = readdir(dir)) != NULL) {
if (ent->d_name[0] == '.')
continue;
snprintf(buf, sizeof(buf), "%s/%s", progPath, ent->d_name);
DMESG("FN: %s", ent->d_name);
// unlink(buf);
}
closedir(dir);
}
//%
void deletePrjFile(String filename) {
if (strlen(filename->data) > 500 || strchr(filename->data, '/'))
return;
char buf[1024];
snprintf(buf, sizeof(buf), "%s/%s", progPath, filename->data);
unlink(buf);
}
//%
RefCollection *listPrjFiles() {
auto res = Array_::mk(0);
//registerGCObj(res);
auto dp = opendir(progPath);
for (;;) {
dirent *ep = dp ? readdir(dp) : NULL;
if (!ep)
break;
if (ep->d_name[0] == '.')
continue;
auto str = mkString(ep->d_name, -1);
//registerGCObj(str);
res->push((TValue)str);
//unregisterGCObj(str);
}
if (dp)
closedir(dp);
//unregisterGCObj(res);
return res;
}
} // namespace pxt

View File

@ -1,6 +1,6 @@
//% color="#68C3E2" weight=100 icon="\uf106"
//% groups='["Buttons", "Screen", "Battery"]'
//% groups='["Buttons", "Screen"]'
//% labelLineWidth=60
namespace brick {
}

View File

@ -1,6 +1,6 @@
{
"name": "pxt-ev3",
"version": "1.1.18",
"version": "1.1.17",
"description": "LEGO MINDSTORMS EV3 for Microsoft MakeCode",
"private": false,
"keywords": [