Compare commits
8 Commits
Author | SHA1 | Date | |
---|---|---|---|
79ead74af4 | |||
0f8ff95b72 | |||
05028c4527 | |||
4054da3483 | |||
7052d27d6d | |||
365af8d672 | |||
c938618d29 | |||
91321dab83 |
@ -7,8 +7,11 @@ serial.writeLine("");
|
||||
serial.writeNumber(0);
|
||||
serial.writeValue("x", 0);
|
||||
serial.writeString("");
|
||||
serial.readUntil(",");
|
||||
serial.readLine();
|
||||
serial.readString();
|
||||
serial.redirect(SerialPin.P0, SerialPin.P0, BaudRate.BaudRate115200);
|
||||
serial.onDataReceived(",", () => {})
|
||||
```
|
||||
|
||||
### See Also
|
||||
|
29
docs/reference/serial/on-data-received.md
Normal file
29
docs/reference/serial/on-data-received.md
Normal file
@ -0,0 +1,29 @@
|
||||
# Serial On Data Received
|
||||
|
||||
Registers an event to be fired when one of the delimiter is matched.
|
||||
|
||||
|
||||
```sig
|
||||
serial.onDataReceived(",", () => {})
|
||||
```
|
||||
|
||||
### Parameters
|
||||
|
||||
* `delimiters` is a [string](/reference/types/string) containing any of the character to match
|
||||
|
||||
### Example
|
||||
|
||||
Read values separated by `,`:
|
||||
|
||||
```blocks
|
||||
serial.onDataReceived(serial.delimiters(Delimiters.Comma), () => {
|
||||
basic.showString(serial.readUntil(serial.delimiters(Delimiters.Comma)))
|
||||
})
|
||||
```
|
||||
|
||||
### See also
|
||||
|
||||
[serial](/device/serial),
|
||||
[serial write line](/reference/serial/write-line),
|
||||
[serial write value](/reference/serial/write-value)
|
||||
|
27
docs/reference/serial/read-string.md
Normal file
27
docs/reference/serial/read-string.md
Normal file
@ -0,0 +1,27 @@
|
||||
# Serial Read String
|
||||
|
||||
Read the buffered serial data as a string
|
||||
|
||||
```sig
|
||||
serial.readString();
|
||||
```
|
||||
|
||||
### Returns
|
||||
|
||||
* a [string](/reference/types/string) containing input from the serial port. Empty if no data available.
|
||||
|
||||
### Example
|
||||
|
||||
The following program scrolls text on the screen as it arrives from serial.
|
||||
|
||||
```blocks
|
||||
basic.forever(() => {
|
||||
basic.showString(serial.readString());
|
||||
});
|
||||
```
|
||||
|
||||
### See also
|
||||
|
||||
[serial](/device/serial),
|
||||
[serial write line](/reference/serial/write-line),
|
||||
[serial write value](/reference/serial/write-value)
|
@ -231,8 +231,10 @@
|
||||
"pins.spiWrite|param|value": "Data to be sent to the SPI slave",
|
||||
"serial": "Reading and writing data over a serial connection.",
|
||||
"serial.delimiters": "Returns the delimiter corresponding string",
|
||||
"serial.onLineReceived": "Registers an event to be fired when a line has been received",
|
||||
"serial.onDataReceived": "Registers an event to be fired when one of the delimiter is matched.",
|
||||
"serial.onDataReceived|param|delimiters": "the characters to match received characters against.",
|
||||
"serial.readLine": "Reads a line of text from the serial port.",
|
||||
"serial.readString": "Reads the buffered received data as a string",
|
||||
"serial.readUntil": "Reads a line of text from the serial port and returns the buffer when the delimiter is met.",
|
||||
"serial.readUntil|param|delimiter": "text delimiter that separates each text chunk",
|
||||
"serial.redirect": "Dynamically configuring the serial instance to use pins other than USBTX and USBRX.",
|
||||
|
@ -171,7 +171,9 @@
|
||||
"pins.spiWrite|block": "spi write %value",
|
||||
"pins|block": "pins",
|
||||
"serial.delimiters|block": "%del",
|
||||
"serial.onDataReceived|block": "serial|on data received %delimiters=serial_delimiter_conv",
|
||||
"serial.readLine|block": "serial|read line",
|
||||
"serial.readString|block": "serial|read string",
|
||||
"serial.readUntil|block": "serial|read until %delimiter=serial_delimiter_conv",
|
||||
"serial.redirect|block": "serial|redirect to|TX %tx|RX %rx|at baud rate %rate",
|
||||
"serial.writeLine|block": "serial|write line %text",
|
||||
|
@ -150,15 +150,9 @@ namespace pxt {
|
||||
|
||||
if (i < length)
|
||||
{
|
||||
if (data[i] != Segment::MissingValue)
|
||||
{
|
||||
return data[i];
|
||||
}
|
||||
error(ERR_MISSING_VALUE);
|
||||
return 0;
|
||||
}
|
||||
error(ERR_OUT_OF_BOUNDS);
|
||||
return 0;
|
||||
return Segment::DefaultValue;
|
||||
}
|
||||
|
||||
void Segment::set(uint32_t i, uint32_t value)
|
||||
@ -223,12 +217,8 @@ namespace pxt {
|
||||
{
|
||||
memcpy(tmp, data, size * sizeof(uint32_t));
|
||||
}
|
||||
|
||||
//fill the rest with missing values;
|
||||
for(uint16_t i = size; i < newSize; i++)
|
||||
{
|
||||
tmp[i] = Segment::MissingValue;
|
||||
}
|
||||
//fill the rest with default value
|
||||
memset(tmp + size, Segment::DefaultValue, (newSize - size) * sizeof(uint32_t));
|
||||
|
||||
//free older segment;
|
||||
::operator delete(data);
|
||||
@ -280,12 +270,11 @@ namespace pxt {
|
||||
if (length > 0)
|
||||
{
|
||||
uint32_t value = data[length];
|
||||
data[length] = Segment::MissingValue;
|
||||
data[length] = Segment::DefaultValue;
|
||||
--length;
|
||||
return value;
|
||||
}
|
||||
error(ERR_OUT_OF_BOUNDS);
|
||||
return 0;
|
||||
return Segment::DefaultValue;
|
||||
}
|
||||
|
||||
//this function removes an element at index i and shifts the rest of the elements to
|
||||
@ -306,15 +295,14 @@ namespace pxt {
|
||||
memmove(data + i, data + i + 1, (length - i - 1) * sizeof(uint32_t));
|
||||
}
|
||||
length--;
|
||||
data[length] = Segment::MissingValue;
|
||||
data[length] = Segment::DefaultValue;
|
||||
#ifdef DEBUG_BUILD
|
||||
printf("After Segment::remove index:%u\n", i);
|
||||
this->print();
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
error(ERR_OUT_OF_BOUNDS);
|
||||
return 0;
|
||||
return Segment::DefaultValue;
|
||||
}
|
||||
|
||||
//this function inserts element value at index i by shifting the rest of the elements right.
|
||||
@ -360,32 +348,13 @@ namespace pxt {
|
||||
|
||||
bool Segment::isValidIndex(uint32_t i)
|
||||
{
|
||||
if (i > length || data[i] == Segment::MissingValue)
|
||||
if (i > length)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Segment::getNextValidIndex(uint32_t i, uint32_t *result)
|
||||
{
|
||||
while (i < length)
|
||||
{
|
||||
if (data[i] != Segment::MissingValue)
|
||||
{
|
||||
*result = i;
|
||||
|
||||
#ifdef DEBUG_BUILD
|
||||
printf("In Segment::getNextValidIndex result=%u\n",i);
|
||||
this->print();
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Segment::destroy()
|
||||
{
|
||||
#ifdef DEBUG_BUILD
|
||||
@ -415,29 +384,16 @@ namespace pxt {
|
||||
|
||||
uint32_t RefCollection::getAt(int i)
|
||||
{
|
||||
if (head.isValidIndex(i))
|
||||
uint32_t tmp = head.get(i);
|
||||
if (isRef())
|
||||
{
|
||||
uint32_t tmp = head.get(i);
|
||||
if (isRef())
|
||||
{
|
||||
incr(tmp);
|
||||
}
|
||||
return tmp;
|
||||
}
|
||||
else
|
||||
{
|
||||
error(ERR_OUT_OF_BOUNDS);
|
||||
return 0;
|
||||
incr(tmp);
|
||||
}
|
||||
return tmp;
|
||||
}
|
||||
|
||||
uint32_t RefCollection::removeAt(int i)
|
||||
{
|
||||
if (!head.isValidIndex((uint32_t)i))
|
||||
{
|
||||
error(ERR_OUT_OF_BOUNDS);
|
||||
return 0;
|
||||
}
|
||||
if (isRef())
|
||||
{
|
||||
decr(head.get(i));
|
||||
@ -447,18 +403,11 @@ namespace pxt {
|
||||
|
||||
void RefCollection::insertAt(int i, uint32_t value)
|
||||
{
|
||||
if (i < length())
|
||||
head.insert(i, value);
|
||||
if (isRef())
|
||||
{
|
||||
head.insert(i, value);
|
||||
if (isRef())
|
||||
{
|
||||
incr(value);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
error(ERR_OUT_OF_BOUNDS);
|
||||
}
|
||||
incr(value);
|
||||
}
|
||||
}
|
||||
|
||||
void RefCollection::setAt(int i, uint32_t value)
|
||||
@ -480,26 +429,31 @@ namespace pxt {
|
||||
{
|
||||
StringData *xx = (StringData*)x;
|
||||
uint32_t i = start;
|
||||
while(head.getNextValidIndex(start, &i))
|
||||
while(head.isValidIndex(i))
|
||||
{
|
||||
StringData *ee = (StringData*)head.get(i);
|
||||
if (xx->len == ee->len && memcmp(xx->data, ee->data, xx->len) == 0)
|
||||
if (ee == xx)
|
||||
{
|
||||
//handles ee being null
|
||||
return (int) i;
|
||||
}
|
||||
if (ee && xx->len == ee->len && memcmp(xx->data, ee->data, xx->len) == 0)
|
||||
{
|
||||
return (int)i;
|
||||
}
|
||||
start = i;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
uint32_t i = start;
|
||||
while(head.getNextValidIndex(start, &i))
|
||||
while(head.isValidIndex(i))
|
||||
{
|
||||
if (head.get(i) == x)
|
||||
{
|
||||
return (int)i;
|
||||
}
|
||||
start = i;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
@ -550,12 +504,9 @@ namespace pxt {
|
||||
{
|
||||
if (this->isRef())
|
||||
{
|
||||
uint32_t start = 0;
|
||||
uint32_t i = 0;
|
||||
while(head.getNextValidIndex(start, &i))
|
||||
for(uint32_t i = 0; i < this->head.getLength(); i++)
|
||||
{
|
||||
decr(this->head.get(i));
|
||||
start = i;
|
||||
}
|
||||
}
|
||||
this->head.destroy();
|
||||
|
@ -38,7 +38,6 @@ namespace pxt {
|
||||
ERR_OUT_OF_BOUNDS = 8,
|
||||
ERR_REF_DELETED = 7,
|
||||
ERR_SIZE = 9,
|
||||
ERR_MISSING_VALUE = 10,
|
||||
} ERROR;
|
||||
|
||||
extern const uint32_t functionsAndBytecode[];
|
||||
@ -175,7 +174,7 @@ namespace pxt {
|
||||
uint16_t size;
|
||||
|
||||
static const uint16_t MaxSize = 0xFFFF;
|
||||
static const uint32_t MissingValue = 0x80000000;
|
||||
static const uint32_t DefaultValue = 0x0;
|
||||
|
||||
static uint16_t growthFactor(uint16_t size);
|
||||
void growByMin(uint16_t minSize);
|
||||
@ -197,10 +196,6 @@ namespace pxt {
|
||||
uint32_t remove(uint32_t i);
|
||||
void insert(uint32_t i, uint32_t value);
|
||||
|
||||
//Returns true if there is a valid index greater than or equal to 'i', returns false otherwise
|
||||
//If 'i' is valid returns it in 'result', if not tries to find the next valid
|
||||
//index < length which is valid.
|
||||
bool getNextValidIndex(uint32_t i, uint32_t *result);
|
||||
bool isValidIndex(uint32_t i);
|
||||
|
||||
void destroy();
|
||||
|
@ -51,24 +51,27 @@ namespace serial {
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a line of text from the serial port.
|
||||
*/
|
||||
//% help=serial/read-line
|
||||
//% blockId=serial_read_line block="serial|read line"
|
||||
//% weight=20 blockGap=8
|
||||
StringData* readLine() {
|
||||
return readUntil(ManagedString("\n").leakData());
|
||||
* Reads the buffered received data as a string
|
||||
*/
|
||||
//% blockId=serial_read_buffer block="serial|read string"
|
||||
//% weight=18
|
||||
StringData* readString() {
|
||||
int n = uBit.serial.getRxBufferSize();
|
||||
if (n == 0) return ManagedString("").leakData();
|
||||
return ManagedString(uBit.serial.read(n, MicroBitSerialMode::ASYNC)).leakData();
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers an event to be fired when one of the delimiter is matched
|
||||
* @param delimiters the characters to match received characters against. eg:"\n"
|
||||
* Registers an event to be fired when one of the delimiter is matched.
|
||||
* @param delimiters the characters to match received characters against.
|
||||
*/
|
||||
// help=serial/on-data-received
|
||||
// weight=18
|
||||
//% help=serial/on-data-received
|
||||
//% weight=18 blockId=serial_on_data_received block="serial|on data received %delimiters=serial_delimiter_conv"
|
||||
void onDataReceived(StringData* delimiters, Action body) {
|
||||
uBit.serial.eventOn(ManagedString(delimiters));
|
||||
registerWithDal(MICROBIT_ID_SERIAL, MICROBIT_SERIAL_EVT_DELIM_MATCH, body);
|
||||
// lazy initialization of serial buffers
|
||||
uBit.serial.read(MicroBitSerialMode::ASYNC);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -38,20 +38,20 @@ namespace serial {
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers an event to be fired when a line has been received
|
||||
*/
|
||||
// help=serial/on-line-received
|
||||
// blockId=serial_on_line_received block="serial on line received"
|
||||
// weight=21 blockGap=8
|
||||
export function onLineReceived(body: Action): void {
|
||||
// serial.onDataReceived("\n", body);
|
||||
* Reads a line of text from the serial port.
|
||||
*/
|
||||
//% help=serial/read-line
|
||||
//% blockId=serial_read_line block="serial|read line"
|
||||
//% weight=20 blockGap=8
|
||||
export function readLine(): string {
|
||||
return serial.readUntil(delimiters(Delimiters.NewLine));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the delimiter corresponding string
|
||||
*/
|
||||
//% blockId="serial_delimiter_conv" block="%del"
|
||||
//% weight=1
|
||||
//% weight=1 blockHidden=true
|
||||
export function delimiters(del: Delimiters): string {
|
||||
// even though it might not look like, this is more
|
||||
// (memory) efficient than the C++ implementation, because the
|
||||
|
17
libs/core/shims.d.ts
vendored
17
libs/core/shims.d.ts
vendored
@ -672,12 +672,19 @@ declare namespace serial {
|
||||
function readUntil(delimiter: string): string;
|
||||
|
||||
/**
|
||||
* Reads a line of text from the serial port.
|
||||
* Reads the buffered received data as a string
|
||||
*/
|
||||
//% help=serial/read-line
|
||||
//% blockId=serial_read_line block="serial|read line"
|
||||
//% weight=20 blockGap=8 shim=serial::readLine
|
||||
function readLine(): string;
|
||||
//% blockId=serial_read_buffer block="serial|read string"
|
||||
//% weight=18 shim=serial::readString
|
||||
function readString(): string;
|
||||
|
||||
/**
|
||||
* Registers an event to be fired when one of the delimiter is matched.
|
||||
* @param delimiters the characters to match received characters against.
|
||||
*/
|
||||
//% help=serial/on-data-received
|
||||
//% weight=18 blockId=serial_on_data_received block="serial|on data received %delimiters=serial_delimiter_conv" shim=serial::onDataReceived
|
||||
function onDataReceived(delimiters: string, body: () => void): void;
|
||||
|
||||
/**
|
||||
* Sends a piece of text through Serial connection.
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "pxt-microbit",
|
||||
"version": "0.7.21",
|
||||
"version": "0.7.23",
|
||||
"description": "micro:bit target for PXT",
|
||||
"keywords": [
|
||||
"JavaScript",
|
||||
@ -36,6 +36,6 @@
|
||||
"semantic-ui-less": "^2.2.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"pxt-core": "0.8.11"
|
||||
"pxt-core": "0.8.13"
|
||||
}
|
||||
}
|
||||
|
@ -35,18 +35,14 @@ namespace pxsim.serial {
|
||||
board().writeSerial(s);
|
||||
}
|
||||
|
||||
export function readUntil(del: string): string {
|
||||
return readString();
|
||||
}
|
||||
|
||||
export function readString(): string {
|
||||
return board().serialState.readSerial();
|
||||
}
|
||||
|
||||
export function readLine(): string {
|
||||
return board().serialState.readSerial();
|
||||
}
|
||||
|
||||
export function readUntil(del: string): string {
|
||||
return readLine();
|
||||
}
|
||||
|
||||
export function onDataReceived(delimiters: string, handler: RefAction) {
|
||||
let b = board();
|
||||
b.bus.listen(DAL.MICROBIT_ID_SERIAL, DAL.MICROBIT_SERIAL_EVT_DELIM_MATCH, handler);
|
||||
|
Reference in New Issue
Block a user