gloomyandy wrote:
I'm not sure if it will work with NXC or not, with luck John will comment... Basically you need to be able to open a simple I/O stream to the device. This means having a Bluetooth connection that does not have the Lego 2 byte packet header in use (in leJOS this is known as RAW mode). I'm not sure if NXC supports this (perhaps it does with the enhanced firmware). This is the same sort of connection needed to talk to things like Bluetooth GPS devices, which I think you can do from NXC but I'm not 100% sure...
I've introduced a pair of fields to the Comm module IOMap which let you set the firmware into DATA_MODE_NXT (default for Bluetooth), DATA_MODE_RAW (default for RS485), or DATA_MODE_GPS. BtDataMode and HsDataMode. While working on these changes I also finally noticed that my previously added HsMode field (for setting the RS485 serial port mode) had the wrong offset in the NBCCommon.h header file (which explains why configuring the port to anything other than its default 8N1 mode was not working properly). I have tested setting the HsDataMode to DATA_MODE_NXT so that direct and system commands sent from one NXT to another via RS485 are automatically processed on the receiving side just like what normally happens with incoming USB and Bluetooth data. I have not yet properly tested setting the BtDataMode to values other than DATA_MODE_NXT to make sure everything still works right.
Currently DATA_MODE_GPS and DATA_MODE_RAW are exactly the same. I am considering adding some code to process GPS sentences at the firmware level if the data mode is set to DATA_MODE_GPS but it hasn't happened yet. In RAW mode, in theory, it should just receive whatever data (up to 128 bytes) that the Bluecore chip sends over the open stream and copy that data into the Comm module's bluetooth input buffer.
However, even with the standard NXT firmware it is very easy to receive GPS data via Bluetooth even with the way it expects 2 bytes at the start that specify the length and how it assumes the contents are a direct or system command. It isn't 100% flawless so this kind of approach may not work well with a Bluetooth keyboard. Here's a pretty simple program that shows how to open a stream to a non-NXT bluetooth device and read whatever that device sends to the NXT. A lot of this is file I/O. All you really need is the function that opens the stream if it is not already open and the function that reads the data from the bluetooth input buffer.
Code: Select all
byte OpenFile(string afile)
{
byte handle;
long file_size;
unsigned int rtn_code = CreateFile(afile, 10048, handle);
// If the file already exists, open it with the intent of adding to the data
// that is already there.
if (rtn_code == LDR_FILEEXISTS)
rtn_code = OpenFileAppend(afile, file_size, handle);
NumOut(0, LCD_LINE8, rtn_code);
Wait(SEC_2);
return handle;
}
void RemoteReadGPSData(byte conn)
{
// is the connection still streaming?
if (BTConnectionStreamStatus(conn))
return;
// otherwise re-open the stream
TextOut(0, LCD_LINE7, "open stream");
Wait(SEC_1);
RemoteKeepAlive(conn);
until(RemoteConnectionIdle(conn)) Wait(MS_1);
}
#ifdef __ENHANCED_FIRMWARE
#define ReadBTInputBuffer(_buf) GetBTInputBuffer(0, 128, _buf)
#else
#define ReadBTInputBuffer(_buf) \
do { \
byte b1[64], b2[64]; \
GetBTInputBuffer(0, 64, b1); \
GetBTInputBuffer(64, 64, b2); \
ArrayBuild(_buf, b1, b2); \
} while (0)
#endif
task main()
{
byte handle;
unsigned int cnt;
unsigned long result;
handle = OpenFile("gps.txt");
bool okay = true;
byte buf[128], oldbuf[128];
byte CRLF[2] = {0x13, 0x10};
while (okay) {
// read bytes from bluetooth input buffer
RemoteReadGPSData(CONN_BT1);
ReadBTInputBuffer(buf);
if (buf != oldbuf)
{
ClearScreen();
// write them to a file
TextOut(0, LCD_LINE3, "writing");
result = WriteBytes(handle, buf, cnt);
NumOut(0, LCD_LINE1, result);
okay = (result == LDR_SUCCESS);
cnt = 2;
WriteBytes(handle, CRLF, cnt);
oldbuf = buf;
}
else
{
TextOut(0, LCD_LINE4, "same data");
}
Wait(MS_50);
}
CloseFile(handle);
Wait(SEC_5);
}
John Hansen