Keyboard.press() not working on arduino mkr wifi 1010

Hi, i am new to arduino project and currently want to create a project of 'automatically lock the windows when the seat occupancy is zero' based on OMRON thermal array.
So the idea is to lock the windows when the omron thermal array is not sensing the presence of a person in front of the computer.

Currently i am using Arduino MKR wifi 1010 and i am using the code from seat occupancy project,
I modified the code by adding method lockScreen() that will be accessed whenever the seat occupancy result is 0.

/* includes */
#include <Wire.h>
#include <Keyboard.h>

/* defines */
#define D6T_ADDR 0x0A  // for I2C 7bit address
#define D6T_CMD 0x4C  // for D6T-44L-06/06H, D6T-8L-09/09H, for D6T-1A-01/02

#define N_ROW 16
#define N_PIXEL (4 * 4)
#define N_READ ((N_PIXEL + 1) * 2 + 1)

#define SAMPLE_TIME_0045MS	45
#define SAMPLE_TIME_0090MS	90
#define SAMPLE_TIME_0130MS	130
#define SAMPLE_TIME_0175MS	175
#define SAMPLE_TIME_0215MS	215
#define SAMPLE_TIME_0260MS	260
#define SAMPLE_TIME_0300MS	300
#define SAMPLE_TIME_0345MS	345
#define SAMPLE_TIME_0390MS	390
#define SAMPLE_TIME_0430MS	430
#define SAMPLE_TIME_0475MS	475
#define SAMPLE_TIME_0515MS	515
#define SAMPLE_TIME_0560MS	560
#define SAMPLE_TIME_0600MS	600
#define SAMPLE_TIME_0645MS	645
#define SAMPLE_TIME_0690MS	690
#define SAMPLE_TIME_0730MS	730
#define SAMPLE_TIME_0775MS	775
#define SAMPLE_TIME_0815MS	815
#define SAMPLE_TIME_0860MS	860
#define SAMPLE_TIME_0900MS	900
#define SAMPLE_TIME_0945MS	945
#define SAMPLE_TIME_0990MS	990
#define SAMPLE_TIME_1030MS	1030
#define SAMPLE_TIME_1070MS	1070
#define SAMPLE_TIME_1115MS	1115
#define SAMPLE_TIME_1160MS	1160
#define SAMPLE_TIME_1200MS	1200
#define SAMPLE_TIME_1245MS	1245
#define SAMPLE_TIME_1290MS	1290
#define SAMPLE_TIME_1330MS	1330
#define SAMPLE_TIME_1370MS	1370

#define PARA_0045MS	((uint8_t)0x01)
#define PARA_0090MS	((uint8_t)0x02)
#define PARA_0130MS	((uint8_t)0x03)
#define PARA_0175MS	((uint8_t)0x04)
#define PARA_0215MS	((uint8_t)0x05)
#define PARA_0260MS	((uint8_t)0x06)
#define PARA_0300MS	((uint8_t)0x07)
#define PARA_0345MS	((uint8_t)0x08)
#define PARA_0390MS	((uint8_t)0x09)
#define PARA_0430MS	((uint8_t)0x0A)
#define PARA_0475MS	((uint8_t)0x0B)
#define PARA_0515MS	((uint8_t)0x0C)
#define PARA_0560MS	((uint8_t)0x0D)
#define PARA_0600MS	((uint8_t)0x0E)
#define PARA_0645MS	((uint8_t)0x0F)
#define PARA_0690MS	((uint8_t)0x10)
#define PARA_0730MS	((uint8_t)0x11)
#define PARA_0775MS	((uint8_t)0x12)
#define PARA_0815MS	((uint8_t)0x13)
#define PARA_0860MS	((uint8_t)0x14)
#define PARA_0900MS	((uint8_t)0x15)
#define PARA_0945MS	((uint8_t)0x16)
#define PARA_0990MS	((uint8_t)0x17)
#define PARA_1030MS	((uint8_t)0x18)
#define PARA_1070MS	((uint8_t)0x19)
#define PARA_1115MS	((uint8_t)0x1A)
#define PARA_1160MS	((uint8_t)0x1B)
#define PARA_1200MS	((uint8_t)0x1C)
#define PARA_1245MS	((uint8_t)0x1D)
#define PARA_1290MS	((uint8_t)0x1E)
#define PARA_1330MS	((uint8_t)0x1F)
#define PARA_1370MS	((uint8_t)0x20)

/***** Setting Parameter *****/
#define comparingNumInc 5  // x300 ms   (range: 1 to 39)   (example) 5 -> 1.5 sec
#define comparingNumDec 5  // x300 ms   (range: 1 to 39)   (example) 5 -> 1.5 sec
#define threshHoldInc 10 //  /10 degC   (example) 10 -> 1.0 degC
#define threshHoldDec 10 //  /10 degC   (example) 10 -> 1.0 degC
bool  enablePix[16] = {true, true, true, true, true, true, true, true, true, true, true, true, true, true, true, true};
/****************************/

/***** Setting Parameter 2 *****/
#define samplingTime SAMPLE_TIME_0300MS //ms (Can select only, 45ms, 90ms, 130ms, 175ms, 215ms, 260ms, 300ms, 435ms, 390ms, 430ms, 475ms, 515ms, 560ms, 600ms, 645ms, 690ms, 730ms, 775ms, 815ms, 860ms, 900ms, 945ms, 990ms, 1030ms, 1070ms, 1115ms, 1160ms, 1200ms, 1245ms, 1290ms, 1330ms, 1370ms)
/****************************/

uint8_t rbuf[N_READ];
int16_t pix_data[16] = {0};
int16_t seqData[16][40] = {0};
bool  occuPix[16] = {0};
bool  occuPixFlag = false;
uint8_t  resultOccupancy = 0;
uint16_t  totalCount = 0;

/** JUDGE_occupancy: judge occupancy*/
bool judge_seatOccupancy(void) {
  int i = 0;
  int j = 0;
  for (i = 0; i < 16; i++) {
    for (j = 0; j < 39; j++) {
      seqData[i][39 - j] = seqData[i][38 - j];
    }
    seqData[i][0] = pix_data[i];
  }
  if (totalCount <= comparingNumInc) {
    totalCount++;
  }
  if (totalCount > comparingNumInc) {
    for (i = 0; i < 16; i++) {
      if (enablePix[i] == true) {
        if (occuPix[i] == false) {
          if ((int16_t)(seqData[i][0] - seqData[i][comparingNumInc]) >= (int16_t)threshHoldInc) {
            occuPix[i] = true;
          }
        }
        else {
          if ((int16_t)(seqData[i][comparingNumDec] - seqData[i][0]) >= (int16_t)threshHoldDec) {
            occuPix[i] = false;
          }
        }
      }
    }
    if (resultOccupancy == 0) {
      for (i = 0; i < 16; i++) {
        if (occuPix[i] == true) {
          resultOccupancy = 1;
          break;
        }
      }
    }
    else { //resultOccupancy == true
      occuPixFlag = false;
      for (i = 0; i < 16; i++) {
        if (occuPix[i] == true) {
          occuPixFlag = true;
          break;
        }
        else {
        }
      }
      if (occuPixFlag == false) {
        resultOccupancy = 0;
      }
    }
  }
  return true;
}

uint8_t calc_crc(uint8_t data) {
  int index;
  uint8_t temp;
  for (index = 0; index < 8; index++) {
    temp = data;
    data <<= 1;
    if (temp & 0x80) {
      data ^= 0x07;
    }
  }
  return data;
}

/** <!-- D6T_checkPEC {{{ 1--> D6T PEC(Packet Error Check) calculation.
   calculate the data sequence,
   from an I2C Read client address (8bit) to thermal data end.
*/
bool D6T_checkPEC(uint8_t buf[], int n) {
  int i;
  uint8_t crc = calc_crc((D6T_ADDR << 1) | 1);  // I2C Read address (8bit)
  for (i = 0; i < n; i++) {
    crc = calc_crc(buf[i] ^ crc);
  }
  bool ret = crc != buf[n];
  if (ret) {
    Serial.print("PEC check failed:");
    Serial.print(crc, HEX);
    Serial.print("(cal) vs ");
    Serial.print(buf[n], HEX);
    Serial.println("(get)");
  }
  return ret;
}


/** <!-- conv8us_s16_le {{{1 --> convert a 16bit data from the byte stream.
*/
int16_t conv8us_s16_le(uint8_t* buf, int n) {
  int ret;
  ret = buf[n];
  ret += buf[n + 1] << 8;
  return (int16_t)ret;   // and convert negative.
}


/** <!-- setup {{{1 -->
   1. initialize a Serial port for output.
   2. initialize an I2C peripheral.
*/
void setup() {
  uint8_t para = 0;
  switch (samplingTime) {
    case SAMPLE_TIME_0045MS:
      para = PARA_0045MS;
      break;
    case SAMPLE_TIME_0090MS:
      para = PARA_0090MS;
      break;
    case SAMPLE_TIME_0130MS:
      para = PARA_0130MS;
      break;
    case SAMPLE_TIME_0175MS:
      para = PARA_0175MS;
      break;
    case SAMPLE_TIME_0215MS:
      para = PARA_0215MS;
      break;
    case SAMPLE_TIME_0260MS:
      para = PARA_0260MS;
      break;
    case SAMPLE_TIME_0300MS:
      para = PARA_0300MS;
      break;
    case SAMPLE_TIME_0345MS:
      para = PARA_0345MS;
      break;
    case SAMPLE_TIME_0390MS:
      para = PARA_0390MS;
      break;
    case SAMPLE_TIME_0430MS:
      para = PARA_0430MS;
      break;
    case SAMPLE_TIME_0475MS:
      para = PARA_0475MS;
      break;
    case SAMPLE_TIME_0515MS:
      para = PARA_0515MS;
      break;
    case SAMPLE_TIME_0560MS:
      para = PARA_0560MS;
      break;
    case SAMPLE_TIME_0600MS:
      para = PARA_0600MS;
      break;
    case SAMPLE_TIME_0645MS:
      para = PARA_0645MS;
      break;
    case SAMPLE_TIME_0690MS:
      para = PARA_0690MS;
      break;
    case SAMPLE_TIME_0730MS:
      para = PARA_0730MS;
      break;
    case SAMPLE_TIME_0775MS:
      para = PARA_0775MS;
      break;
    case SAMPLE_TIME_0815MS:
      para = PARA_0815MS;
      break;
    case SAMPLE_TIME_0860MS:
      para = PARA_0860MS;
      break;
    case SAMPLE_TIME_0900MS:
      para = PARA_0900MS;
      break;
    case SAMPLE_TIME_0945MS:
      para = PARA_0945MS;
      break;
    case SAMPLE_TIME_0990MS:
      para = PARA_0990MS;
      break;
    case SAMPLE_TIME_1030MS:
      para = PARA_1030MS;
      break;
    case SAMPLE_TIME_1070MS:
      para = PARA_1070MS;
      break;
    case SAMPLE_TIME_1115MS:
      para = PARA_1115MS;
      break;
    case SAMPLE_TIME_1160MS:
      para = PARA_1160MS;
      break;
    case SAMPLE_TIME_1200MS:
      para = PARA_1200MS;
      break;
    case SAMPLE_TIME_1245MS:
      para = PARA_0945MS;
      break;
    case SAMPLE_TIME_1290MS:
      para = PARA_1290MS;
      break;
    case SAMPLE_TIME_1330MS:
      para = PARA_1330MS;
      break;
    case SAMPLE_TIME_1370MS:
      para = PARA_1370MS;
    default:
      para = PARA_0300MS;
      break;
  }

  Serial.begin(115200);  // Serial baudrate = 115200bps
  Wire.begin();  // i2c master

  Wire.beginTransmission(D6T_ADDR);  // I2C client address
  Wire.write(0x50);                  // D6T register
  Wire.write(0x52);                  // D6T register
  Wire.write(0x45);                  // D6T register
  Wire.write(0x4C);                  // D6T register
  Wire.write(0x45);                  // D6T register
  Wire.write(0x41);                  // D6T register
  Wire.write(0x53);                  // D6T register
  Wire.write(0x45);                  // D6T register
  Wire.write(0x00);                  // D6T register
  Wire.endTransmission();            // I2C repeated start for read
  Wire.beginTransmission(D6T_ADDR);  // I2C client address
  Wire.write(0x42);                  // D6T register
  Wire.write(para);                  // D6T register
  Wire.write(0x00);                  // D6T register
  Wire.endTransmission();            // I2C repeated start for read
  Wire.beginTransmission(D6T_ADDR);  // I2C client address
  Wire.write(0x50);                  // D6T register
  Wire.write(0x00);                  // D6T register
  Wire.write(0x00);                  // D6T register
  Wire.write(0x00);                  // D6T register
  Wire.write(0x00);                  // D6T register
  Wire.write(0x00);                  // D6T register
  Wire.write(0x00);                  // D6T register
  Wire.write(0x00);                  // D6T register
  Wire.write(0x00);                  // D6T register
  Wire.endTransmission();            // I2C repeated start for read

  Keyboard.begin(); //begin control over keyboard
}


/** <!-- loop - Thermal sensor {{{1 -->
   1. read sensor.
   2. output results, format is: [degC]
*/
void loop() {
  int i, j;
  int jj;

  memset(rbuf, 0, N_READ);
  // Wire buffers are enough to read D6T-16L data (33bytes) with
  // MKR-WiFi1010 and Feather ESP32,
  // these have 256 and 128 buffers in their libraries.
  Wire.beginTransmission(D6T_ADDR);  // I2C client address
  Wire.write(D6T_CMD);               // D6T register
  Wire.endTransmission();            // I2C repeated start for read
  delay(1);
  Wire.requestFrom(D6T_ADDR, N_READ);
  i = 0;
  while (Wire.available()) {
    rbuf[i++] = Wire.read();
  }

  if (D6T_checkPEC(rbuf, N_READ - 1)) {
    return;
  }

  // 1st data is PTAT measurement (: Proportional To Absolute Temperature)
  int16_t itemp = conv8us_s16_le(rbuf, 0);
  Serial.print("PTAT:");
  Serial.print(itemp / 10.0, 1);
  Serial.print(", Temperature:");

  // loop temperature pixels of each thrmopiles measurements
  for (i = 0, j = 2; i < N_PIXEL; i++, j += 2) {
    itemp = conv8us_s16_le(rbuf, j);
    pix_data[i] = itemp;
    Serial.print(itemp / 10.0, 1);  // print PTAT & Temperature
    /**********debug ***********************/
    //Serial.print(",");
    //if(occuPix[i] == false){
    //  jj = 0;
    //}
    //else{
    //  jj = 1;
    //}
    //Serial.print(jj, 1);
    /*************************************/
    if ((i % N_ROW) == N_ROW - 1) {
      Serial.print(" [degC]");  // wrap text at ROW end.
    } else {
      Serial.print(", ");   // print delimiter
    }
  }
  judge_seatOccupancy(); //add
  Serial.print(", Occupancy:");
  Serial.println(resultOccupancy, 1);

  //lock windows if no person is detected
  if (resultOccupancy == 0) {
    lockScreen();
    delay(1000);
  }
  delay(samplingTime);
}
// vi: ft=arduino:fdm=marker:et:sw=4:tw=80

void lockScreen() {
  Keyboard.begin();
  Serial.println("pressing");

  Keyboard.press(KEY_LEFT_GUI);

  Keyboard.press('l');

  Keyboard.releaseAll();

  delay(5000);
}

/>

But whenever the seat occupancy equals to 0, it didn't automatically lock the windows.

Please if there's someone who might know the issue, kindly help me. If you need other info regarding to the code/hardware or software that I'm using, just ask.

Thank you!

Please post your complete sketch following the advice given in the link below

link for original github project: d6t-ap-SeatOccupancy-arduino/d6t-44l.ino at master · hankha/d6t-ap-SeatOccupancy-arduino · GitHub

Thank you for trying but it is not quite right

Edit your post, select all of the code and then click the </> icon to add the code tags

Hi, thank you for your kind advised. I edited my post, is it correct? Thank you!

Hi, sorry, i revised it again. Please kindly check, thank you so much!

It looks OK now and is easier to view and copy for anyone offering help

Try this simplified version to see if the locking works:

#include <Keyboard.h>

void setup()
{
  Serial.begin(115200);
  Keyboard.begin(); //begin control over keyboard
  delay(5000);
  lockScreen();
  delay(5000);
}

void loop()
{}


void lockScreen()
{
  Serial.println("Locking");

  Keyboard.press(KEY_LEFT_GUI);

  Keyboard.press('l');

  delay(20);

  Keyboard.releaseAll();
  
  Serial.println("Locked");
}

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.