Reworked driver code, again.
This commit is contained in:
41
bcdriver.cpp
41
bcdriver.cpp
@@ -37,12 +37,6 @@
|
||||
|
||||
|
||||
|
||||
BCDriver::BCDriver(QObject* parent )
|
||||
: QObject{ parent }
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
BCDriver::DriverState BCDriver::getDriverState() const
|
||||
{
|
||||
return _driverState;
|
||||
@@ -59,47 +53,16 @@ BCDriver::DriverState BCDriver::getDriverState() const
|
||||
* aber die Console noch nicht eingeschaltet war.
|
||||
*/
|
||||
|
||||
void BCDriverDummy::onStartDriver()
|
||||
BCDriver::DriverStateResult BCDriverDummy::loadAndStartDriver()
|
||||
{
|
||||
_driverState = DriverState::DeviceReady;
|
||||
emit driverStateChanged( DriverState::DeviceReady, "Driver Ready." );
|
||||
return _driverState;
|
||||
}
|
||||
// __Fix
|
||||
/*
|
||||
try
|
||||
{
|
||||
|
||||
// erstmal die Dll Laden: State::sIdle -> State::sLoaded
|
||||
if( _driverState == DriverState::NotPresent)
|
||||
_driverState = loadAndInitDriver();
|
||||
|
||||
emit stateChanged( _driverState );
|
||||
|
||||
}
|
||||
catch( std::exception& except )
|
||||
{
|
||||
//::CanDownDriver();
|
||||
//::UnloadAndInitDriver();
|
||||
|
||||
emit statusHint( except.what() );
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/// -----------------------------------------------------------------------------------
|
||||
/// -----------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* @brief BCDriverDummy::BCDriverDummy
|
||||
* @param parent
|
||||
*/
|
||||
|
||||
BCDriverDummy::BCDriverDummy( QObject* parent )
|
||||
: BCDriver(parent)
|
||||
{
|
||||
}
|
||||
|
||||
TransmitResult BCDriverDummy::readRawByte( uint32_t deviceID, uint8_t registerID ) const
|
||||
{
|
||||
|
||||
25
bcdriver.h
25
bcdriver.h
@@ -84,9 +84,9 @@ class BCDriverStatus;
|
||||
*/
|
||||
|
||||
|
||||
class BCDriver : public QObject
|
||||
class BCDriver
|
||||
{
|
||||
Q_OBJECT
|
||||
Q_GADGET
|
||||
|
||||
public:
|
||||
|
||||
@@ -96,20 +96,22 @@ public:
|
||||
enum class DriverState
|
||||
{
|
||||
NotPresent,
|
||||
Error,
|
||||
Loaded,
|
||||
Initialized,
|
||||
Opened, // bis hierher: dll vorhanden, Treiber geladen
|
||||
DeviceReady // hier: devices connectable, wir können arbeiten.
|
||||
DeviceReady, // hier: devices connectable, wir können arbeiten.
|
||||
Error,
|
||||
};
|
||||
Q_ENUM(DriverState)
|
||||
|
||||
// Enthält den Treiberzustand oder einen Fehlerstring
|
||||
using DriverStateResult = std::expected<DriverState,QString>;
|
||||
|
||||
explicit BCDriver( QObject* parent = nullptr );
|
||||
explicit BCDriver() = default;
|
||||
virtual ~BCDriver() = default;
|
||||
|
||||
virtual BCDriver::DriverStateResult loadAndStartDriver() = 0;
|
||||
|
||||
// Gibt den aktuelle Zustand des Treibers zurück. Der DriverState
|
||||
// muss auf DeviceReady stehen, um Werte lesen & schreiben zu können.
|
||||
// Dazu muss das Bionx-System eingeschaltet sein.
|
||||
@@ -122,14 +124,6 @@ public:
|
||||
virtual TransmitResult readRawByte ( uint32_t deviceID, uint8_t registerID ) const = 0;
|
||||
virtual TransmitResult writeRawByte( uint32_t deviceID, uint8_t registerID, uint8_t value ) const = 0;
|
||||
|
||||
public slots:
|
||||
|
||||
virtual void onStartDriver() = 0;
|
||||
|
||||
signals:
|
||||
|
||||
void driverStateChanged( DriverState state, const QString& message="" ) const;
|
||||
|
||||
protected:
|
||||
|
||||
DriverState _driverState{DriverState::NotPresent};
|
||||
@@ -139,18 +133,15 @@ protected:
|
||||
|
||||
class BCDriverDummy : public BCDriver
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
explicit BCDriverDummy( QObject* parent = nullptr );
|
||||
BCDriver::DriverStateResult loadAndStartDriver() override;
|
||||
|
||||
TransmitResult readRawByte( uint32_t deviceID, uint8_t registerID ) const override;
|
||||
TransmitResult writeRawByte( uint32_t deviceID, uint8_t registerID, uint8_t value ) const override;
|
||||
|
||||
public slots:
|
||||
|
||||
virtual void onStartDriver() override;
|
||||
};
|
||||
|
||||
#endif // BCDRIVER_H
|
||||
|
||||
@@ -36,44 +36,56 @@
|
||||
#include <can_drv.h>
|
||||
|
||||
|
||||
/**
|
||||
* @brief Destruktor. Entlädt den CAN-Bus Treiber wieder.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
BCDriverTinyCan::BCDriverTinyCan( QObject* parent )
|
||||
: BCDriver(parent )
|
||||
BCDriverTinyCan::~BCDriverTinyCan()
|
||||
{
|
||||
|
||||
resetDriver();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief BCDriverTinyCan::loadAndStartDriver
|
||||
* @return
|
||||
*/
|
||||
|
||||
void BCDriverTinyCan::onStartDriver()
|
||||
BCDriver::DriverStateResult BCDriverTinyCan::loadAndStartDriver()
|
||||
{
|
||||
DriverStateResult result;
|
||||
if( _driverState < DriverState::Opened)
|
||||
loadDriver();
|
||||
result = loadDriver();
|
||||
if( _driverState == DriverState::Opened)
|
||||
_driverState = connectDriver();
|
||||
result = setConsoleSlaveMode();
|
||||
return result;
|
||||
}
|
||||
|
||||
void BCDriverTinyCan::loadDriver()
|
||||
/**
|
||||
* @brief BCDriverTinyCan::loadDriver
|
||||
* @return
|
||||
*/
|
||||
|
||||
BCDriver::DriverStateResult BCDriverTinyCan::loadDriver()
|
||||
{
|
||||
|
||||
|
||||
auto callLoadDriver = []() -> DriverStateResult
|
||||
auto callLoadDriver = [&]() -> DriverStateResult
|
||||
{
|
||||
if( ::LoadDriver( NULL ) < 0 )
|
||||
return std::unexpected(QString("Driver Error: 'LoadDriver'"));
|
||||
return DriverState::Loaded;
|
||||
_driverState = DriverState::Loaded;
|
||||
return _driverState;
|
||||
};
|
||||
|
||||
auto callInitDriver = [](DriverState state) -> DriverStateResult
|
||||
auto callInitDriver = [&](DriverState state) -> DriverStateResult
|
||||
{
|
||||
Q_UNUSED(state)
|
||||
if( ::CanInitDriver( NULL ) < 0 )
|
||||
return std::unexpected(QString("Driver Error: 'InitDriver'"));
|
||||
return DriverState::Initialized;
|
||||
_driverState = DriverState::Initialized;
|
||||
return _driverState;
|
||||
};
|
||||
|
||||
auto callOpenDevice = [](DriverState state) -> DriverStateResult
|
||||
auto callOpenDevice = [&](DriverState state) -> DriverStateResult
|
||||
{
|
||||
Q_UNUSED(state)
|
||||
if( ::CanDeviceOpen( 0, NULL ) < 0 )
|
||||
@@ -93,27 +105,64 @@ void BCDriverTinyCan::loadDriver()
|
||||
::CanSetMode( 0, OP_CAN_RESET, CAN_CMD_NONE );
|
||||
return std::unexpected(QString("Driver Error: CAN Status 'BusOff'" ));
|
||||
}
|
||||
return DriverState::Opened;
|
||||
_driverState = DriverState::Opened;
|
||||
return _driverState;
|
||||
};
|
||||
|
||||
|
||||
// #1. erstmal komplett zurücksetzen
|
||||
resetDriver();
|
||||
// #2. Treiber laden, initialisieren und
|
||||
// mit dem tinyCan Interface verbinden.
|
||||
auto newDriverState = callLoadDriver()
|
||||
.and_then( callInitDriver )
|
||||
.and_then( callOpenDevice );
|
||||
|
||||
_driverState = DriverState::Error;
|
||||
QString message("Driver Ready.");
|
||||
|
||||
// success:
|
||||
if(newDriverState)
|
||||
_driverState = *newDriverState;
|
||||
else
|
||||
message = newDriverState.error();
|
||||
{
|
||||
// return 'DriverState::Opened'
|
||||
return _driverState;
|
||||
}
|
||||
// return driver error message,
|
||||
// _driverState ist irgendwo unter DriverState::Opened
|
||||
return newDriverState;
|
||||
|
||||
emit driverStateChanged( _driverState, message );
|
||||
}
|
||||
|
||||
// __fix
|
||||
BCDriver::DriverState BCDriverTinyCan::connectDriver()
|
||||
BCDriver::DriverStateResult BCDriverTinyCan::setConsoleSlaveMode()
|
||||
{
|
||||
/*
|
||||
consoleInSlaveMode = getValue(CONSOLE, CONSOLE_STATUS_SLAVE);
|
||||
|
||||
if (consoleInSlaveMode)
|
||||
{
|
||||
printf("console already in salve mode. good!" _NL _NL);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gConsoleSetSlaveMode)
|
||||
{
|
||||
int retry = 20;
|
||||
|
||||
printf("putting console in salve mode ... ");
|
||||
do {
|
||||
setValue(CONSOLE, CONSOLE_STATUS_SLAVE, 1);
|
||||
consoleInSlaveMode = getValue(CONSOLE, CONSOLE_STATUS_SLAVE);
|
||||
usleep(200000);
|
||||
} while(retry-- && !consoleInSlaveMode);
|
||||
|
||||
doSleep(500); // give the console some time to settle
|
||||
printf("%s" _NL _NL, consoleInSlaveMode ? "done" : "failed");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("console not in slave mode" _NL _NL);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
uint32_t console = static_cast<uint32_t>(BCDevice::ID::Console);
|
||||
uint8_t slaveFlag = static_cast<uint8_t>(BC::ID::Cons_Status_Slave);
|
||||
|
||||
@@ -126,7 +175,7 @@ BCDriver::DriverState BCDriverTinyCan::connectDriver()
|
||||
qDebug() << "BCDriverTinyCan::BCDriverTinyCan::XXX Driver Init: putting Console in slave mode ... ";
|
||||
|
||||
unsigned int retry = cTimeOuts;
|
||||
emit driverStateChanged( _driverState, "Driver Init: putting Console in slave mode ... " );
|
||||
|
||||
TransmitResult isSlave = 0;
|
||||
do
|
||||
{
|
||||
@@ -145,20 +194,15 @@ BCDriver::DriverState BCDriverTinyCan::connectDriver()
|
||||
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
try
|
||||
{
|
||||
initBCDevice::ID::Console();
|
||||
}
|
||||
|
||||
catch( std::exception& except )
|
||||
void BCDriverTinyCan::resetDriver()
|
||||
{
|
||||
if( _driverState > DriverState::NotPresent )
|
||||
{
|
||||
::CanDownDriver();
|
||||
::UnloadDriver();
|
||||
_driverState = DriverState::NotPresent;
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief BCDriverTinyCan::readRawByte
|
||||
@@ -173,7 +217,7 @@ TransmitResult BCDriverTinyCan::readRawByte( uint32_t deviceID, uint8_t register
|
||||
//TransmitResult
|
||||
qDebug() << " --- BCDriverTinyCan::readRawByte DriverState: " << getDriverState();
|
||||
|
||||
if( getDriverState() != DriverState::DeviceReady)
|
||||
if( _driverState != DriverState::DeviceReady)
|
||||
return std::unexpected(QString("readRawValue error: driver not loaded." ) );
|
||||
|
||||
::TCanMsg msg;
|
||||
@@ -238,7 +282,7 @@ retry:
|
||||
TransmitResult BCDriverTinyCan::writeRawByte( uint32_t deviceID, uint8_t registerID ,uint8_t value ) const
|
||||
{
|
||||
|
||||
if( getDriverState() != DriverState::DeviceReady)
|
||||
if( _driverState != DriverState::DeviceReady)
|
||||
return std::unexpected(QString("writeRawValue error: driver not loaded." ) );
|
||||
|
||||
qDebug() << " --- BCDriverTinyCan writeRawValue: " << value;
|
||||
|
||||
@@ -37,24 +37,22 @@
|
||||
|
||||
class BCDriverTinyCan : public BCDriver
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
explicit BCDriverTinyCan( QObject* parent=nullptr );
|
||||
virtual ~BCDriverTinyCan() = default;
|
||||
|
||||
virtual ~BCDriverTinyCan();
|
||||
|
||||
BCDriver::DriverStateResult loadAndStartDriver() override;
|
||||
|
||||
TransmitResult readRawByte ( uint32_t deviceID, uint8_t registerID ) const override;
|
||||
TransmitResult writeRawByte( uint32_t deviceID, uint8_t registerID, uint8_t value ) const override;
|
||||
|
||||
public slots:
|
||||
private:
|
||||
|
||||
void onStartDriver() override;
|
||||
|
||||
protected:
|
||||
|
||||
void loadDriver();
|
||||
DriverState connectDriver();
|
||||
BCDriver::DriverStateResult loadDriver();
|
||||
BCDriver::DriverStateResult setConsoleSlaveMode();
|
||||
void resetDriver();
|
||||
|
||||
//const char* CBCDLL_LIN = "libmhstcan.so";
|
||||
//const char* CBCDLL_WIN = "mhstcan.dll";
|
||||
|
||||
35
bclegacy.cpp
35
bclegacy.cpp
@@ -727,24 +727,30 @@ int xmain(int argc, char **argv)
|
||||
CanSetMode(0, OP_CAN_START, CAN_CMD_ALL_CLEAR);
|
||||
CanGetDeviceStatus(0, &status);
|
||||
|
||||
if (status.DrvStatus >= DRV_STATUS_CAN_OPEN) {
|
||||
if (status.CanStatus == CAN_STATUS_BUS_OFF) {
|
||||
if (status.DrvStatus >= DRV_STATUS_CAN_OPEN)
|
||||
{
|
||||
if (status.CanStatus == CAN_STATUS_BUS_OFF)
|
||||
{
|
||||
printf("CAN Status BusOff" _NL);
|
||||
CanSetMode(0, OP_CAN_RESET, CAN_CMD_NONE);
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("error: could not open device" _NL);
|
||||
goto error;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
consoleInSlaveMode = getValue(CONSOLE, CONSOLE_STATUS_SLAVE);
|
||||
if (consoleInSlaveMode) {
|
||||
|
||||
if (consoleInSlaveMode)
|
||||
{
|
||||
printf("console already in salve mode. good!" _NL _NL);
|
||||
} else {
|
||||
if (gConsoleSetSlaveMode) {
|
||||
}
|
||||
else
|
||||
{
|
||||
if (gConsoleSetSlaveMode)
|
||||
{
|
||||
int retry = 20;
|
||||
|
||||
printf("putting console in salve mode ... ");
|
||||
@@ -756,16 +762,21 @@ int xmain(int argc, char **argv)
|
||||
|
||||
doSleep(500); // give the console some time to settle
|
||||
printf("%s" _NL _NL, consoleInSlaveMode ? "done" : "failed");
|
||||
} else
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("console not in slave mode" _NL _NL);
|
||||
}
|
||||
}
|
||||
|
||||
if (gAssistInitLevel != -1) {
|
||||
if (gAssistInitLevel != -1)
|
||||
{
|
||||
printf("setting initial assistance level to %d" _NL, gAssistInitLevel);
|
||||
setValue(CONSOLE, CONSOLE_ASSIST_INITLEVEL, gAssistInitLevel);
|
||||
}
|
||||
|
||||
if (gSetSpeedLimit > 0) {
|
||||
if (gSetSpeedLimit > 0)
|
||||
{
|
||||
printf("set speed limit to %0.2f km/h" _NL, gSetSpeedLimit);
|
||||
setSpeedLimit(gSetSpeedLimit);
|
||||
doShutdown = 1;
|
||||
|
||||
@@ -143,7 +143,7 @@ void BCMainWindow::initMainWindow()
|
||||
*/
|
||||
// besser: model::emit dataChanged
|
||||
// also: emit dataChanged(index, index, {Qt::DisplayRole, Qt::EditRole, ValueRole});
|
||||
connect( _connectButton, &QToolButton::clicked, &_transmitter, &BCTransmitter::onToggleConnectionState );
|
||||
connect( _connectButton, &QToolButton::clicked, &_transmitter, &BCTransmitter::onToggleDriverConnection );
|
||||
connect( _syncButton, &QToolButton::clicked, this, &BCMainWindow::onSyncDeviceView );
|
||||
connect( &_transmitter, &BCTransmitter::valueUpdated, this, &BCMainWindow::onValueUpdated );
|
||||
|
||||
|
||||
@@ -35,37 +35,61 @@
|
||||
|
||||
#include <bctransmitter.h>
|
||||
|
||||
/**
|
||||
* @brief Kosntruktion. Aktiviert erstmal den Dummy-Driver.
|
||||
*/
|
||||
|
||||
BCTransmitter::BCTransmitter(QObject *parent)
|
||||
: QObject(parent), _isBusy(false)
|
||||
{
|
||||
//_canDriver = new BCDriverTinyCan{this};
|
||||
_canDriver = new BCDriverDummy{this};
|
||||
// forward driver state
|
||||
connect( _canDriver, &BCDriver::driverStateChanged, this, &BCTransmitter::driverStateChanged );
|
||||
_canDriver = &_dummyDriver;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Steuert die Verbindung mit dem 'echten' CAN-Bus Treiber.
|
||||
* @param connect true: Vesuche den CAN-Bus Treiber zu laden und zu verbinden
|
||||
* false: Disconnect & Cleanup
|
||||
*/
|
||||
|
||||
void BCTransmitter::onToggleConnectionState( bool connect )
|
||||
void BCTransmitter::onToggleDriverConnection( bool connect )
|
||||
{
|
||||
if( connect )
|
||||
{
|
||||
if( _canDriver->getDriverState() != BCDriver::DriverState::DeviceReady )
|
||||
_canDriver->onStartDriver();
|
||||
qDebug() << " --- onToggleDriverConnection: " << connect;
|
||||
// FIX! Ende der current op abwarten!
|
||||
// weitere operation stoppen
|
||||
_isBusy = true;
|
||||
|
||||
// __fix!
|
||||
TransmitResult hwVersion = _canDriver->readRawByte( (uint32_t)BCDevice::ID::Console, (uint8_t)BC::ID::Cons_Rev_Hw);
|
||||
if(!hwVersion)
|
||||
connect ? connectCanDriver() : disconnectCanDriver();
|
||||
|
||||
}
|
||||
|
||||
void BCTransmitter::connectCanDriver()
|
||||
{
|
||||
// hier gehts nur um den echten Treiber
|
||||
|
||||
// Treiber laden und/oder starten:
|
||||
if( _tinyCanDriver.getDriverState() != BCDriver::DriverState::DeviceReady )
|
||||
_tinyCanDriver.loadAndStartDriver();
|
||||
|
||||
// hat geklappt
|
||||
if( _tinyCanDriver.getDriverState() == BCDriver::DriverState::DeviceReady )
|
||||
{
|
||||
uint32_t console = static_cast<uint32_t>(BCDevice::ID::Console);
|
||||
uint8_t hwRev = static_cast<uint8_t> (BC::ID::Cons_Rev_Hw);
|
||||
|
||||
TransmitResult hwVersion = _tinyCanDriver.readRawByte( console, hwRev);
|
||||
if( hwVersion.has_value() )
|
||||
qDebug() << " ---- HAIL to the king!";
|
||||
else
|
||||
qDebug() << "Console not responding";
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
void BCTransmitter::disconnectCanDriver()
|
||||
{
|
||||
|
||||
qDebug() << " ---HAIL to the kings: " << hwVersion.value();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -60,12 +60,9 @@ public:
|
||||
|
||||
explicit BCTransmitter(QObject *parent = nullptr);
|
||||
|
||||
//TransmitResult readByte( uint32_t deviceID, uint8_t registerID ) const override;
|
||||
//TransmitResult writeByte( uint32_t deviceID, uint8_t registerID, uint8_t value ) const override;
|
||||
|
||||
public slots:
|
||||
|
||||
void onToggleConnectionState( bool connect );
|
||||
void onToggleDriverConnection( bool connect );
|
||||
void enqueueValue(BCValuePtrConst value );
|
||||
void processValue();
|
||||
|
||||
@@ -76,11 +73,11 @@ signals:
|
||||
|
||||
private:
|
||||
|
||||
void connectCanDriver();
|
||||
void disconnectCanDriver();
|
||||
|
||||
TransmitResult readByteValue( uint32_t deviceID, uint8_t registerID );
|
||||
TransmitResult readWordValue( uint32_t deviceID, uint8_t registerID );
|
||||
//TransmitResult writeByteValue( uint32_t deviceID, uint8_t registerID );
|
||||
//TransmitResult writeWordValue( uint32_t deviceID, uint8_t registerID );
|
||||
|
||||
|
||||
using BCDataQueue = QQueue<BCValuePtrConst>;
|
||||
|
||||
@@ -88,8 +85,10 @@ private:
|
||||
QMutex _mutex;
|
||||
std::atomic<bool> _isBusy{ false };
|
||||
|
||||
// __fix! set two
|
||||
// __fix!
|
||||
BCDriver* _canDriver{};
|
||||
BCDriverTinyCan _tinyCanDriver{};
|
||||
BCDriverDummy _dummyDriver{};
|
||||
|
||||
};
|
||||
|
||||
|
||||
@@ -56,8 +56,6 @@
|
||||
-
|
||||
*/
|
||||
|
||||
|
||||
|
||||
using OptDouble = std::optional<double>;
|
||||
|
||||
// Enthält den gelesenen Wert oder einen Fehlerstring
|
||||
@@ -65,8 +63,6 @@ using TransmitResult = std::expected<uint32_t,QString>;
|
||||
// Funktionsobject, um Werte aus der Transmitterschicht zu holden
|
||||
//using ReadValueFunc = std::function<TransmitResult( const BCAbstractTransmitter& transmitter, uint32_t deviceID, uint8_t registerID )>;
|
||||
|
||||
|
||||
|
||||
class BCValue
|
||||
{
|
||||
|
||||
|
||||
BIN
doc/Challenges.docx
Normal file
BIN
doc/Challenges.docx
Normal file
Binary file not shown.
|
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 46 KiB |
@@ -1,7 +1,9 @@
|
||||
Challenges
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------------------------
|
||||
|
||||
BionxControl
|
||||
|
||||
Aufgabe:
|
||||
|
||||
@@ -10,12 +12,9 @@ Ansatz:
|
||||
-------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
Aufgabe:
|
||||
|
||||
Ansatz:
|
||||
|
||||
-------------------------------------------------------------------------------------------------
|
||||
|
||||
xtree
|
||||
|
||||
Aufgabe:
|
||||
|
||||
@@ -23,6 +22,7 @@ Ansatz:
|
||||
|
||||
-------------------------------------------------------------------------------------------------
|
||||
|
||||
znode
|
||||
|
||||
Aufgabe:
|
||||
|
||||
@@ -30,6 +30,7 @@ Ansatz:
|
||||
|
||||
-------------------------------------------------------------------------------------------------
|
||||
|
||||
libPigPio
|
||||
|
||||
Aufgabe:
|
||||
|
||||
@@ -37,6 +38,23 @@ Ansatz:
|
||||
|
||||
-------------------------------------------------------------------------------------------------
|
||||
|
||||
supportware
|
||||
|
||||
Aufgabe:
|
||||
|
||||
Ansatz:
|
||||
|
||||
-------------------------------------------------------------------------------------------------
|
||||
|
||||
raDIYo
|
||||
|
||||
Aufgabe:
|
||||
|
||||
Ansatz:
|
||||
|
||||
-------------------------------------------------------------------------------------------------
|
||||
|
||||
miniCash.connect
|
||||
|
||||
Aufgabe:
|
||||
|
||||
|
||||
BIN
doc/~$allenges.docx
Normal file
BIN
doc/~$allenges.docx
Normal file
Binary file not shown.
BIN
doc/~WRL0643.tmp
Normal file
BIN
doc/~WRL0643.tmp
Normal file
Binary file not shown.
Reference in New Issue
Block a user