Die JetiExSensor-Lib von Bernd ist so getimed, dass sie alle 150 ms ein Frame mit einer maximalen Länge von 29 Byte sendet. Der Header jedes Frames ist 8 Byte lang und am Ende kommen nochmals 1 Byte für CRC. Somit bleiben 20 Bytes für die Datenblöcke. Das erste Byte eines Datenblocks beinhaltet den Index des Werts und den Datentyp. Danach kommen die eigentlichen Datenbytes. Beim Datentyp 14b sind es 2 Datenbytes. Beim Typ 14b ist somit ein Datenblock 3 Bytes lang und ein Frame kann maximal 6 Werte senden.
Um 32 Werte vom Typ 14b vom Sensor an den Emfpänger zu senden braucht es 7 Frames und damit 7 * 150 ms = 1050 ms. Dies entspricht ziemlich genau dem mittleren Updateintervall von 1061 ms in dem Log von Ingmar. Damit ist klar dass die Umsetzung des Protokolls der Flaschenhals ist.
@Ingmar: Teste doch mal, was passiert wenn du die Senderintervalle in Bernds Library auf 50 ms oder noch weniger setzt. Die Updateintervalle in den Logs müssten entsprechend kürzer werden. Evtl. akzeptiert der Emfpänger auch Frames welche länger als 29 Bytes sind.
uint8_t JetiExProtocol::DoJetiSend()
{
// send every 150 ms only
if( ( m_tiLastSend + 150 ) <= millis() )
{
m_tiLastSend = millis();
// navigator exit
if( m_bExitNav )
{
SendJetiboxExit();
m_bExitNav = false;
}
// morse alarm
else if( m_alarmChar )
{
SendJetiAlarm( m_alarmChar );
m_alarmChar = 0;
}
// EX frame...
else if( m_pSensorsConst )
{
SendExFrame( m_frameCnt++ );
}
// followed by "simple text" frame
SendJetiboxTextFrame();
}
return 0;
}
void JetiExProtocol::SendExFrame( uint8_t frameCnt )
{
uint8_t n = 0;
uint8_t i = 0;
// sensor name in frame 0
if( frameCnt == 0 )
{ // sensor name
m_exBuffer[2] = 0x00; // 2Bit packet type(0-3) 0x40=Data, 0x00=Text
m_exBuffer[8] = 0x00; // 8Bit id
m_exBuffer[9] = m_nameLen<<3; // 5Bit description, 3Bit unit length (use one space character)
memcpy( m_exBuffer + 10, m_name, m_nameLen ); // copy label plus unit to ex buffer starting from pos 10
n += m_nameLen + 10;
}
// sensor dictionary: use the first few frames with even numbers to transfer
else if( ( (frameCnt/2) <= m_nSensors && (frameCnt % 2) == 0 ) )
{
for( int nDict = 0; nDict < m_nSensors; nDict++ )
{
JetiSensor sensor( m_dictIdx, this );
if( ++m_dictIdx >= m_nSensors )
m_dictIdx = 0;
if( sensor.m_bActive )
{
m_exBuffer[2] = 0x00; // 2Bit packet type(0-3) 0x40=Data, 0x00=Text
m_exBuffer[8] = sensor.m_id; // 8Bit id
m_exBuffer[9] = (sensor.m_textLen<<3) | sensor.m_unitLen; // 5Bit description, 3Bit unit length
n = sensor.jetiCopyLabel( m_exBuffer, 10 ) + 10; // copy label plus unit to ex buffer starting from pos 10
break;
}
}
}
// send EX values in all other frames
else
{
int bufLen;
int nVal = 0; // count values
m_exBuffer[ 2 ] = 0x40; // 2Bit Type(0-3) 0x40=Data, 0x00=Text
n=8; // start at nineth byte in buffer
do
{
bufLen = 0; // last value buffer length
JetiSensor sensor( m_sensorIdx, this );
if( ++m_sensorIdx >= m_nSensors ) // wrap index when array is at the end
m_sensorIdx = 0;
if( sensor.m_bActive && sensor.m_value != -1 ) // -1 is "invalid"
{
if( sensor.m_id > 15 )
{
m_exBuffer[n++] = 0x0 | (sensor.m_dataType & 0x0F); // sensor id > 15 --> put id to next byte
m_exBuffer[n++] = sensor.m_id;
}
else
m_exBuffer[n++] = (sensor.m_id<<4) | (sensor.m_dataType & 0x0F); // 4Bit id, 4 bit data type (i.e. int14_t)
bufLen = sensor.m_bufLen;
n += sensor.jetiEncodeValue( m_exBuffer, n );
}
if( ++nVal >= m_nSensors ) // dont send twice in a frame
break;
}
while( n < ( 26 - bufLen ) ); // jeti spec says max 29 Bytes per buffer
}
Gruss Lukas