--- In [email protected], "Geert Vancompernolle" <[EMAIL PROTECTED]> wrote: > > As a sequel to the hint Edwin gave (poll your pin(s)), maybe the code > below can serve as a starting point: > > void C8575Io::Execute( void ) > { > FUNCLOG( "Execute( void )" ); > > struct timeval tvTimeVal; > unsigned int uiWhileCounter = 0; > unsigned int uiRow = 0; > unsigned int uiColumn = 0; > unsigned int uiTimeDelta = 0; > unsigned int uiCheckPattern = 0; > > LOG( "C8575Io - Running thread object in a new thread: %d" > , (int)GetThreadID() > ); > > tvTimeVal.tv_sec = 0; > > while ( !bTerminateThread ) > { > tvTimeVal.tv_usec = 10000; /* 10ms is minimal timer tick of > system */ > > select( 0, NULL, NULL, NULL, &tvTimeVal); > > /* Compose bitcheck pattern */ > uiCheckPattern = 0; > > /* Check which pins have to be observed for this 10ms timeslot */ > for ( uiRow = 0; uiRow <= PORT1; uiRow++ ) > { > for ( uiColumn = 0; uiColumn <= PINMAX; uiColumn++ ) > { > if ( Expander.PollTime[ uiRow ][ uiColumn ] ) > { > if ( ( uiWhileCounter % Expander.PollTime[ uiRow > ][ uiColumn ] ) == 0 ) > { > uiCheckPattern |= ( 1 << ( ( uiRow * 8 ) + > uiColumn ) ); > } > } > } > } > > /* Are there any pins to be checked for this 10ms timeslot? */ > if ( uiCheckPattern ) > { > unsigned int uiResult = GetBytes(); > unsigned int uiMask = 0x01; > > uiRow = 0; > uiColumn = 0; > > while ( uiMask != 0x10000 ) > { > if ( uiCheckPattern & uiMask ) /* This bit has to be > checked */ > { > if ( !( uiResult & uiMask ) ) > { /* Button has been pressed */ > Expander.CurrPinVal |= uiMask; > > if ( ( Expander.CurrPinVal & uiMask ) != ( > Expander.PrevPinVal & uiMask ) ) > { > Expander.CurrTimeVal[ uiRow ][ uiColumn ] > = uiWhileCounter; > Expander.PrevTimeVal[ uiRow ][ uiColumn ] > = Expander.CurrTimeVal[ uiRow ][ uiColumn ]; > Expander.PrevPinVal = Expander.CurrPinVal; > } > } > else > { /* Button has been released */ > Expander.CurrPinVal &= ~uiMask; /* Reset pin > value */ > > if ( ( Expander.CurrPinVal & uiMask ) != ( > Expander.PrevPinVal & uiMask ) ) > { > Expander.CurrTimeVal[ uiRow ][ uiColumn ] > = uiWhileCounter; > > if ( Expander.CurrTimeVal[ uiRow ][ > uiColumn ] >= Expander.PrevTimeVal[ uiRow ][ uiColumn ] ) > { > uiTimeDelta = Expander.CurrTimeVal[ > uiRow ][ uiColumn ] > - Expander.PrevTimeVal[ > uiRow ][ uiColumn ]; > } > else > { > uiTimeDelta = Expander.CurrTimeVal[ > uiRow ][ uiColumn ] > + ( UINT_MAX - > Expander.PrevTimeVal[ uiRow ][ uiColumn ] ); > } > > Expander.PrevTimeVal[ uiRow ][ uiColumn ] > = Expander.CurrTimeVal[ uiRow ][ uiColumn ] = 0; > Expander.PrevPinVal = Expander.CurrPinVal; > > MyIoMqStruct.MsgType = 2; > MyIoMqStruct.MqUn.IoStruct.IoPin = ( uiRow > * 8 ) + uiColumn; > MyIoMqStruct.MqUn.IoStruct.Time = ( > uiTimeDelta * 10 ); > > // LOG( "PCF85755 - Button %d pressed for > about %d ms..." > // , ( uiRow * 8 ) + uiColumn > // , ( uiTimeDelta * 10 ) /* compensate > for time slot */ > // ); > /* Info gathered, so send it to message > queue... */ > if ( CMqMgrUnique::GetMqId() >= 0 ) > { > CMqMgrUnique::SendMsg( (struct > MqStruct*)&MyIoMqStruct > , sizeof( > MyIoMqStruct ) > , 0 > ); > } > } > } > } > > uiMask <<= 1; > uiColumn++; > > if ( uiMask == 0x0100 ) > { > uiColumn = 0; > uiRow++; > } > } > } > > uiWhileCounter++; > } > > LOG( "Quitting 8575 Exectute()\n" ); > } /* Execute */ > > > The above code is polling the status of IO pins of an PCF8575. Each > pin can have a different polling time (for instance, pin 0 can be > polled every 50ms, but pin 14 can be polled every 30ms). > The basics is a separate thread where this function "Execute()" is > running in. > The "while" loop you see, is running every 10ms (so, the polling times > that can be assigned to each and every IO pin individually must be a > multiple of 10ms). > To avoid almost 100% occupation of the CPU power, the function > "select()" is used to put the process/thread into sleep for about 10ms. > In fact, I should say "misused", since I profit from the time-out > value you can specify for that function before it returns. So, since > no parameters are given, the function will wait for input that will > never come. So, it will time-out after (in my case) 10ms. > This reduces the CPU time occupied by this application to next to 0% > (almost nothing). > If you don't do this, then your CPU will be busy almost 100% doing > this loop! > > This is a very robust way of polling input pins. If I see that your > requirements are to poll a pin every 10 seconds, then there's a > tremendous amount of time free for the processor to do other things. > > The code is given just as an example code, to show you that with using > the correct set-up, many interrupts can be replaced by polling > techniques. Many, but not all, of course. A lot depends on the > requirements you give, but in your case that should absolutely not be > any problem at all... > > Best rgds, > > --Geert >
Thanks alot for your help. But I think I will try the hint Edwin give me. Becaus i do not understand what you are doing in here. If i get more familare withe the board i will try you result. Best regards grack
