add c version for esp8266

add c version for esp8266

error: pathspec 'c_version/esp8266/Udp_server.ino' did not match any file(s) known to git

--- c_version/esp8266/Udp_server.ino
+++ c_version/esp8266/Udp_server.ino
@@ -0,0 +1,753 @@
+#include <ESP8266WiFi.h>
+#include <WiFiUdp.h>
+#include <string>
+
+#include <string>
+
+std::string SALT;
+
+class MD5
+{
+#define S11 7
+#define S12 12
+#define S13 17
+#define S14 22
+#define S21 5
+#define S22 9
+#define S23 14
+#define S24 20
+#define S31 4
+#define S32 11
+#define S33 16
+#define S34 23
+#define S41 6
+#define S42 10
+#define S43 15
+#define S44 21
+
+public:
+  typedef unsigned int size_type; // must be 32bit
+
+  static std::string checkSum(std::string text)
+  {
+    MD5 pmd5(text);
+    return pmd5.getstring();
+  }
+
+  MD5() { init(); }
+  MD5(const std::string& text) {
+    init();
+    update((const unsigned char*)text.c_str(), text.length());
+    finalize();
+  }
+  void update(const unsigned char input[], size_type length) {
+    // compute number of bytes mod 64
+    size_type index = count[0] / 8 % blocksize;
+
+    // Update number of bits
+    if ((count[0] += (length << 3)) < (length << 3))
+      count[1]++;
+    count[1] += (length >> 29);
+
+    // number of bytes we need to fill in buffer
+    size_type firstpart = 64 - index;
+
+    size_type i;
+
+    // transform as many times as possible.
+    if (length >= firstpart)
+    {
+      // fill buffer first, transform
+      memcpy(&buffer[index], input, firstpart);
+      transform(buffer);
+
+      // transform chunks of blocksize (64 bytes)
+      for (i = firstpart; i + blocksize <= length; i += blocksize)
+        transform(&input[i]);
+
+      index = 0;
+    }
+    else
+      i = 0;
+
+    // buffer remaining input
+    memcpy(&buffer[index], &input[i], length - i);
+  }
+  MD5& finalize() {
+    static unsigned char padding[64] = {
+      0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+      0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+    };
+
+    if (!finalized) {
+      // Save number of bits
+      unsigned char bits[8];
+      encode(bits, count, 8);
+
+      // pad out to 56 mod 64.
+      size_type index = count[0] / 8 % 64;
+      size_type padLen = (index < 56) ? (56 - index) : (120 - index);
+      update(padding, padLen);
+
+      // Append length (before padding)
+      update(bits, 8);
+
+      // Store state in digest
+      encode(digest, state, 16);
+
+      // Zeroize sensitive information.
+      memset(buffer, 0, sizeof buffer);
+      memset(count, 0, sizeof count);
+
+      finalized = true;
+    }
+
+    return *this;
+  }
+
+  unsigned char* getResult() {
+    return  (unsigned char*)this->digest;
+  }
+  std::string getstring() {
+    return std::string((const char*)this->digest, (size_t)16);
+  }
+private:
+  void init() {
+    finalized = false;
+
+    count[0] = 0;
+    count[1] = 0;
+
+    // load magic initialization constants.
+    state[0] = 0x67452301;
+    state[1] = 0xefcdab89;
+    state[2] = 0x98badcfe;
+    state[3] = 0x10325476;
+  }
+  typedef unsigned char uint1; //  8bit
+  typedef unsigned int uint4;  // 32bit
+  enum { blocksize = 64 }; // VC6 won't eat a const static int here
+
+  void transform(const uint1 block[blocksize]) {
+    uint4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
+    decode(x, block, blocksize);
+
+    /* Round 1 */
+    FF(a, b, c, d, x[0], S11, 0xd76aa478); /* 1 */
+    FF(d, a, b, c, x[1], S12, 0xe8c7b756); /* 2 */
+    FF(c, d, a, b, x[2], S13, 0x242070db); /* 3 */
+    FF(b, c, d, a, x[3], S14, 0xc1bdceee); /* 4 */
+    FF(a, b, c, d, x[4], S11, 0xf57c0faf); /* 5 */
+    FF(d, a, b, c, x[5], S12, 0x4787c62a); /* 6 */
+    FF(c, d, a, b, x[6], S13, 0xa8304613); /* 7 */
+    FF(b, c, d, a, x[7], S14, 0xfd469501); /* 8 */
+    FF(a, b, c, d, x[8], S11, 0x698098d8); /* 9 */
+    FF(d, a, b, c, x[9], S12, 0x8b44f7af); /* 10 */
+    FF(c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
+    FF(b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
+    FF(a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
+    FF(d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
+    FF(c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
+    FF(b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
+
+    /* Round 2 */
+    GG(a, b, c, d, x[1], S21, 0xf61e2562); /* 17 */
+    GG(d, a, b, c, x[6], S22, 0xc040b340); /* 18 */
+    GG(c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
+    GG(b, c, d, a, x[0], S24, 0xe9b6c7aa); /* 20 */
+    GG(a, b, c, d, x[5], S21, 0xd62f105d); /* 21 */
+    GG(d, a, b, c, x[10], S22, 0x2441453); /* 22 */
+    GG(c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
+    GG(b, c, d, a, x[4], S24, 0xe7d3fbc8); /* 24 */
+    GG(a, b, c, d, x[9], S21, 0x21e1cde6); /* 25 */
+    GG(d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
+    GG(c, d, a, b, x[3], S23, 0xf4d50d87); /* 27 */
+    GG(b, c, d, a, x[8], S24, 0x455a14ed); /* 28 */
+    GG(a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
+    GG(d, a, b, c, x[2], S22, 0xfcefa3f8); /* 30 */
+    GG(c, d, a, b, x[7], S23, 0x676f02d9); /* 31 */
+    GG(b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
+
+    /* Round 3 */
+    HH(a, b, c, d, x[5], S31, 0xfffa3942); /* 33 */
+    HH(d, a, b, c, x[8], S32, 0x8771f681); /* 34 */
+    HH(c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
+    HH(b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
+    HH(a, b, c, d, x[1], S31, 0xa4beea44); /* 37 */
+    HH(d, a, b, c, x[4], S32, 0x4bdecfa9); /* 38 */
+    HH(c, d, a, b, x[7], S33, 0xf6bb4b60); /* 39 */
+    HH(b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
+    HH(a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
+    HH(d, a, b, c, x[0], S32, 0xeaa127fa); /* 42 */
+    HH(c, d, a, b, x[3], S33, 0xd4ef3085); /* 43 */
+    HH(b, c, d, a, x[6], S34, 0x4881d05); /* 44 */
+    HH(a, b, c, d, x[9], S31, 0xd9d4d039); /* 45 */
+    HH(d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
+    HH(c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
+    HH(b, c, d, a, x[2], S34, 0xc4ac5665); /* 48 */
+
+    /* Round 4 */
+    II(a, b, c, d, x[0], S41, 0xf4292244); /* 49 */
+    II(d, a, b, c, x[7], S42, 0x432aff97); /* 50 */
+    II(c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
+    II(b, c, d, a, x[5], S44, 0xfc93a039); /* 52 */
+    II(a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
+    II(d, a, b, c, x[3], S42, 0x8f0ccc92); /* 54 */
+    II(c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
+    II(b, c, d, a, x[1], S44, 0x85845dd1); /* 56 */
+    II(a, b, c, d, x[8], S41, 0x6fa87e4f); /* 57 */
+    II(d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
+    II(c, d, a, b, x[6], S43, 0xa3014314); /* 59 */
+    II(b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
+    II(a, b, c, d, x[4], S41, 0xf7537e82); /* 61 */
+    II(d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
+    II(c, d, a, b, x[2], S43, 0x2ad7d2bb); /* 63 */
+    II(b, c, d, a, x[9], S44, 0xeb86d391); /* 64 */
+
+    state[0] += a;
+    state[1] += b;
+    state[2] += c;
+    state[3] += d;
+
+    // Zeroize sensitive information.
+    memset(x, 0, sizeof x);
+  }
+  static void decode(uint4 output[], const uint1 input[], size_type len) {
+    for (unsigned int i = 0, j = 0; j < len; i++, j += 4)
+      output[i] = ((uint4)input[j]) | (((uint4)input[j + 1]) << 8) |
+      (((uint4)input[j + 2]) << 16) | (((uint4)input[j + 3]) << 24);
+  }
+  static void encode(uint1 output[], const uint4 input[], size_type len) {
+    for (size_type i = 0, j = 0; j < len; i++, j += 4) {
+      output[j] = input[i] & 0xff;
+      output[j + 1] = (input[i] >> 8) & 0xff;
+      output[j + 2] = (input[i] >> 16) & 0xff;
+      output[j + 3] = (input[i] >> 24) & 0xff;
+    }
+  }
+
+  bool finalized;
+  uint1 buffer[blocksize]; // bytes that didn't fit in last 64 byte chunk
+  uint4 count[2];   // 64bit counter for number of bits (lo, hi)
+  uint4 state[4];   // digest so far
+  uint1 digest[16]; // the result
+
+  // low level logic operations
+  static inline uint4 Fl(uint4 x, uint4 y, uint4 z) {
+    return x & y | ~x & z;
+  }
+  static inline uint4 G(uint4 x, uint4 y, uint4 z) {
+    return x & z | y & ~z;
+  }
+  static inline uint4 H(uint4 x, uint4 y, uint4 z) {
+    return x ^ y ^ z;
+  }
+  static inline uint4 I(uint4 x, uint4 y, uint4 z) {
+    return y ^ (x | ~z);
+  }
+  static inline uint4 rotate_left(uint4 x, int n) {
+    return (x << n) | (x >> (32 - n));
+  }
+  static inline void FF(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac) {
+    a = rotate_left(a + Fl(b, c, d) + x + ac, s) + b;
+  }
+  static inline void GG(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac) {
+    a = rotate_left(a + G(b, c, d) + x + ac, s) + b;
+  }
+  static inline void HH(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac) {
+    a = rotate_left(a + H(b, c, d) + x + ac, s) + b;
+  }
+  static inline void II(uint4& a, uint4 b, uint4 c, uint4 d, uint4 x, uint4 s, uint4 ac) {
+    a = rotate_left(a + I(b, c, d) + x + ac, s) + b;
+  }
+
+};
+
+std::string hexToString(std::string hexStr)
+{
+  char hexTabel[] = { '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f' };
+  std::string ret;
+  for (auto& e : hexStr)
+  {
+    ret += hexTabel[((unsigned char)e) / 0x10];
+    ret += hexTabel[((unsigned char)e) % 0x10];
+  }
+  return ret;
+}
+
+std::string stringToHex(std::string hexstring)
+{
+  auto getInt = [](char c)
+  {
+    char hexTabel[] = { '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f' };
+    for (int i = 0; i < 16; i++)
+    {
+      if (c == hexTabel[i])
+        return i;
+    }
+  };
+  std::string ret;
+  for (int i = 0, a; i < hexstring.size(); i += 2)
+  {
+    a = getInt(hexstring[i]) << 4;
+    a += getInt(hexstring[i + 1]);
+    ret.append(1, (unsigned char)a);
+  }
+  return ret;
+}
+
+int hexToInt(std::string hexstr)
+{
+  auto getInt = [](char c)
+  {
+    char hexTabel[] = { '0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f' };
+    for (int i = 0; i < 16; i++)
+    {
+      if (c == hexTabel[i])
+        return i;
+    }
+  };
+  int ret = 0;
+  for (int i = 0; i < 4; i++)
+    ret += getInt(hexstr[i]) << (28 - (i * 4));
+  return ret;
+}
+
+long long strToLong(std::string hexstr)
+{
+  unsigned long long ret = 0;
+  int size = hexstr.size() - 1;
+  for (int i = 0; i < hexstr.size(); i ++)
+  {
+    unsigned long long num = (unsigned long long)((unsigned char)hexstr[i]);
+    ret += (num) << ((size - i) * 8);
+  }
+  return ret;
+}
+
+class UDPSocket
+{
+public:
+  UDPSocket()
+  {
+        Udp.begin(61440);
+  }
+  ~UDPSocket()
+  {
+  }
+
+  void SendTo(const std::string& address, unsigned short port, const char* buffer, int len)
+  {
+    Udp.beginPacket(address.c_str(), port);
+    Udp.write(buffer, len);
+    Udp.endPacket();
+  }
+
+  bool RecvFrom(char* buffer, int len, int flags = 0)
+  {
+    long long frq = 0;
+    while (frq < 8342363)
+    {
+      int packetSize = Udp.parsePacket();
+      if(packetSize > 0)
+      {
+        int n = Udp.read(buffer, len);
+        buffer[n] = 0;
+        return true;
+      }
+      frq++;
+    }
+    return false;
+  }
+private:
+  WiFiUDP Udp;
+};
+
+struct expand_type {
+  template<typename... T>
+  expand_type(T&&...) {}
+};
+
+template<typename... ArgTypes>
+void log(ArgTypes... args)
+{
+  expand_type{ (  Serial.print(args.c_str()), 0)... };
+  Serial.printf("\n");
+}
+
+
+UDPSocket s;
+
+std::string challenge(std::string svr, int ran)
+{
+    while (1)
+    {
+      std::string ret;
+      std::string send;
+
+      int randNum = ran % 0xffff;
+      send.append("\01\02");
+
+      send.append(1, (unsigned char)((randNum << 24) >> 24));
+      send.append(1, (unsigned char)(randNum >> 8));
+
+      send.append("\x09");
+      send.append(15, (char)0x0);
+      s.SendTo(svr, 61440, send.c_str(), send.size());
+
+        ret.resize(1024);
+        s.RecvFrom((char*)ret.c_str(), ret.length());
+        log(std::string("[challenge] recv "), hexToString(ret));
+        return ret.substr(4, 4);
+    }
+    return std::string();
+}
+
+std::string dump(long long n)
+{
+  std::string ret;
+  bool start = 0;
+  for (int i = 0; i < 8; i++)
+  {
+    char ad = (n << (i * 8)) >> 56;
+    if (ad != 0)
+      start = 1;
+    if (start)
+      ret += ad;
+  }
+  return ret;
+}
+
+std::string mkpkt(std::string salt, std::string usr, std::string pwd, long long mac)
+{
+
+  std::string data = "\x03\x01";
+  data.append(1, (char)0x0);
+  data += (char)(usr.size() + 20);
+
+  data.append(MD5::checkSum(std::string("\3\1") + salt + pwd));
+  data.append(usr);
+  data.append(36 - usr.size(), (char)0x0);
+  data.append("\x20");// CONTROLCHECKSTATUS
+  data.append("\1");// adpter num
+
+  std::string dumpstr = dump(strToLong(data.substr(4, 6)) ^ mac);
+  data += dumpstr.substr(dumpstr.size() - 6);
+
+  std::string checkStr = std::string("\x01") + pwd + salt;
+  checkStr.append(4, (char)0x0);
+  data += MD5::checkSum(checkStr);
+
+  data += "\x01";
+  data += "\xa\x1e\x16\x11"; // host_ip
+
+  data.append(12, (char)0x0);
+
+  checkStr = data + std::string("\x14");
+  checkStr.append(1, (char)0x0);
+  checkStr += "\x07\x0B";
+  data += MD5::checkSum(checkStr).substr(0, 8);
+
+  data += "\x01"; //IPDOG
+  data.append(4, (char)0x0);
+
+  std::string host_name = "LIYUANYUAN";
+  data.append(host_name);
+  data.append(32 - host_name.size(), 0x0);
+  data.append(4, (char)114);// dns
+  data.append(4, (char)0);// _tagHostInfo.DHCPServerIP
+  data.append(12, (char)0);
+  data += "\x94";
+  data.append(3, (char)0);
+  data += "\x05";   // _tagHostInfo.OSVersion.MajorVersion
+  data.append(3, (char)0);
+  data += "\x01";   // _tagHostInfo.OSVersion.MinorVersion
+  data.append(3, (char)0);
+  data += "\x28\x0A";   // _tagHostInfo.OSVersion.BuildNumber
+  data.append(2, (char)0);
+  data += "\x02";   // _tagHostInfo.OSVersion.PlatformID
+  data.append(3, (char)0);
+
+  std::string host_os = "8089DA";
+  data.append(host_os);
+  data.append(32 - host_os.size(), 0x0);
+  data.append(96, (char)0);
+
+  data += "\x0a"; // AUTH_VERSION
+  data.append(1, (char)0);
+
+  //data += ror(MD5::checkSum(std::string("\x03\x01") + salt + pwd), pwd);
+
+  auto checksum = [](std::string st) -> std::string
+  {
+    int ret = 1234;
+    int i = 0;
+    st.append(4, (char)0);
+    for (; i < st.length() - 4; i += 4)
+    {
+      std::string bf = st.substr(i, 4);
+      int num = (int)((unsigned char)bf[3] << 24);
+      num += (int)(((unsigned char)bf[2]) << 16 );
+      num += (int)(((unsigned char)bf[1]) << 8);
+      num += (int)(((unsigned char)bf[0]));
+      ret ^= num;
+    }
+    ret = (1968 * ret) & 0xffffffff;
+    std::string r;
+    r += ((unsigned char)ret) >> 24;
+    r += (((unsigned char)ret) << 24) >> 24;
+    r += (((unsigned char)ret) << 16) >> 24;
+    r += (((unsigned char)ret) << 8) >> 24;
+    return r;
+  };
+  data += "\x02";
+  data += "\x0c";
+
+  std::string sumStr;
+  sumStr = data + std::string("\x01\x26\x07\x11");
+  sumStr.append(2, (char)0x0);
+  sumStr += dump(mac);
+  data += checksum(sumStr);
+
+  data.append(2, (char)0);
+  data += dump(mac);
+  data.append(2, (char)0);
+
+  data += "\xE9\x13";
+  return data;
+}
+
+std::string DRlogin(std::string username, std::string password, std::string server)
+{
+  std::string ret;
+  ret.resize(1024);
+  for (int i = 0; i < 5; i++)
+  {
+    //SALT = challenge(server, GetSystemTimeAsUnixTime() + ((rand() % 0xf0) + 0xf));
+    SALT = challenge(server, (rand() % 0xffff));
+
+    std::string packet = mkpkt(SALT, username, password, 0x54e1ad1af086);
+    log(std::string("[login] send "), hexToString(packet));
+    s.SendTo(server, 61440, packet.c_str(), packet.size());
+    s.RecvFrom((char*)ret.c_str(), ret.length());
+    log(std::string("[login] recv "), hexToString(ret));
+    log(std::string("[login] packet sent."));
+    if (ret[0] == *"\x04")
+    {
+      log(std::string("[login] loged in"));
+      break;
+    }
+    else
+      delay(2000);
+  }
+  return ret.substr(23, 16);
+}
+
+std::string keep_alive_package_builder(int number, std::string tail, int type = 1, bool first = false)
+{
+  std::string data = "\x07";
+  data.append(1, (char)number);
+  data += "\x28";
+  data.append(1, (char)0x0);
+  data += "\x0B";
+  data.append(1, (char)type);
+
+  if (first)
+    data += "\x0F\x27";
+  else
+    data += "\xdc\x02"; // KEEP_ALIVE_VERSION
+  data += "\x2F\x12";
+  data.append(6, (char)0x0);
+  data += tail;
+  data.append(4, (char)0x0);
+  if (type == 3)
+  {
+    data.append(4, (char)0x0);
+    data += "\x10\x30\x22\x17";
+    data.append(8, (char)0x0);
+  }
+  else
+    data.append(16, (char)0x0);
+  return data;
+}
+
+bool keep_alive1(std::string salt, std::string tail, std::string pwd, std::string svr)
+{
+  std::string data = "\xff" + MD5::checkSum("\x03\x01" + salt + pwd);
+  data.append(3, (char)0x0);
+  data += tail;
+  unsigned int randNum = (rand()) % 0xffff;
+
+  data.append(1, (char)((randNum) >> 8));
+  data.append(1, (char)(((randNum) << 24) >> 24));
+
+
+  data.append(4, (char)0x0);
+
+  log(std::string("[keep_alive1] send "), hexToString(data));
+
+  s.SendTo(svr, 61440, data.data(), data.size());
+
+  while (1)
+  {
+    std::string ret;
+    ret.resize(1024);
+    if (!s.RecvFrom((char*)ret.c_str(), ret.length()))
+      return false;
+    if (ret[0] == *"\x07")
+    {
+      log(std::string("[keep_alive1] recv "), hexToString(ret));
+      break;
+    }
+  }
+
+}
+
+void keep_alive2(std::string salt, std::string tail, std::string pwd, std::string svr)
+{
+  auto compareStr = [](const char* str1, const char* str2, int size) -> bool
+  {
+    for (int i = 0; i < size; i++)
+    {
+      if (str1[i] != str2[i])
+        return false;
+    }
+    return true;
+  };
+  std::string ttail;
+  ttail.append(4, (char)0x0);
+
+  std::string otail = tail;
+
+  std::string data;
+  data.resize(1024);
+
+  int svr_num = 0;
+  std::string packet = keep_alive_package_builder(svr_num, ttail, 1, true);
+
+  while (1)
+  {
+    log(std::string("[keep-alive2] send1 "), hexToString(packet));
+    s.SendTo(svr, 61440, packet.data(), packet.size());
+
+
+    s.RecvFrom((char*)data.c_str(), data.length());
+    log(std::string("[keep-alive2] recv1 "), hexToString(data));
+
+    if (compareStr(data.c_str(), "\x07\x00\x28\x00", 4))
+    {
+      std::string cstr = "\x07";
+      for (int i = 0; i < svr_num; i++)
+        cstr.append(1, (char)0x0);
+      cstr += "\x28";
+      cstr.append(1, (char)0x0);
+      if (compareStr(data.c_str(), cstr.c_str(), svr_num + 3))
+        break;
+    }
+    else if (data[0] == 0x7 && data[2] == 0x10)
+    {
+      log(std::string("[keep-alive2] recv file, resending.."));
+      svr_num = svr_num + 1;
+      break;
+    }
+    else
+    {
+      log(std::string("[keep-alive2] recv1/unexpected"), hexToString(data));
+    }
+  }
+
+  packet = keep_alive_package_builder(svr_num, ttail, 1, false);
+  log(std::string("[keep-alive2] send2"), hexToString(packet));
+  s.SendTo(svr, 61440, packet.data(), packet.size());
+  while (1)
+  {
+    s.RecvFrom((char*)data.c_str(), data.length());
+    if (data[0] == 0x7)
+    {
+      svr_num = svr_num + 1;
+      tail = data.substr(16, 4);
+      log(std::string("[keep-alive2] recv2"), hexToString(data));
+      break;
+    }
+    else
+      log(std::string("[keep-alive2] recv2/unexpected"), hexToString(data));
+  }
+
+  packet = keep_alive_package_builder(svr_num, tail, 3, false);
+  s.SendTo(svr, 61440, packet.data(), packet.size());
+  while (1)
+  {
+    s.RecvFrom((char*)data.c_str(), data.length());
+    if (data[0] == 0x7)
+    {
+      svr_num = svr_num + 1;
+      tail = data.substr(16, 4);
+      log(std::string("[keep-alive2] recv3"), hexToString(data));
+      log(std::string("[keep-alive2] keep-alive2 loop was in daemon."));
+      break;
+    }
+  }
+  while (1)
+  {
+
+      delay(20000);
+      if (!keep_alive1(salt, otail, pwd, svr))
+        return;
+      packet = keep_alive_package_builder(svr_num, tail, 1, false);
+      log(std::string("[keep_alive2] send "), hexToString(packet));
+      s.SendTo(svr, 61440, packet.data(), packet.size());
+
+      s.RecvFrom((char*)data.c_str(), data.length());
+      log(std::string("[keep_alive2] recv "), hexToString(data));
+
+      tail = data.substr(16, 4);
+
+      packet = keep_alive_package_builder(svr_num + 1, tail, 3, false);
+      s.SendTo(svr, 61440, packet.data(), packet.size());
+      log(std::string("[keep_alive2] send "), hexToString(packet));
+
+      s.RecvFrom((char*)data.c_str(), data.length());
+      tail = data.substr(16, 4);
+      log(std::string("[keep_alive2] recv "), hexToString(data));
+
+      if (tail == "")
+        return;
+      svr_num = (svr_num + 2) % 127;
+
+
+  }
+
+
+}
+
+  char server[] = "192.168.211.3";
+  char username[] = "账号"; // 这里登录账号
+  char password[] = "密码"; // 这里登录密码
+
+void setup() {
+  Serial.begin(115200);
+
+  Serial.print("start connect");
+  WiFi.mode(WIFI_STA);
+  WiFi.begin(" 账号 ", " 密码 "); // 这里wifi账号密码
+  while (WiFi.status() != WL_CONNECTED) {
+    Serial.print('.');
+    delay(500);
+  }
+  Serial.print("Connected! IP address: ");
+  Serial.println(WiFi.localIP());
+  Serial.printf("UDP server on port %d\n", 8880);
+
+
+  log(std::string("auth svr: "), std::string(server), std::string("\nusername: "), std::string(username), std::string("\npassword: "), std::string(password), std::string("\nmac: "));
+  log(std::string("bind ip: "), std::string("0.0.0.0"));
+}
+
+
+void loop() {
+
+    std::string package_tail = DRlogin(username, password, server);
+    if(keep_alive1(SALT, package_tail, password, server))
+       keep_alive2(SALT, package_tail, password, server);
+}


Modified header

Modified header

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/anidea/fx300_sequence_detect.git/'


Add the Arduino source for controlling X90100 programmable capacitor

error: pathspec 'files/Arduino/apr19_x90100_trim_cap/apr19_usb_comm.ino' did not match any file(s) known to git

--- files/Arduino/apr19_x90100_trim_cap/apr19_usb_comm.ino
+++ files/Arduino/apr19_x90100_trim_cap/apr19_usb_comm.ino
@@ -0,0 +1,85 @@
+// This program can the capacitance values of two programmable capacitors (Intersil X90100) via USB serial communication
+// Syntax: Axx will change the value Capacitor A, Bxx will change the value of Capacitor B, where xx is a number between 0 and 31
+
+// Reference: http://arduinobasics.blogspot.com/2012/07/arduino-basics-simple-arduino-serial.html
+String inString;
+// Buffer to store incoming commands from serial port;
+// String method can be found at http://arduino.cc/en/Reference/StringObject
+
+int UD = 8;
+int INC = 9;
+int CS0 = 10;
+int CS1 = 11;
+
+void setup() {
+    pinMode(UD, OUTPUT);
+    pinMode(INC, OUTPUT);
+    pinMode(CS0, OUTPUT);
+    pinMode(CS1, OUTPUT);
+    digitalWrite(CS0, HIGH);
+    digitalWrite(CS1, HIGH);
+    digitalWrite(INC, HIGH);  // INC is negative-edge triggered
+    digitalWrite(UD, HIGH);
+    Serial.begin(9600);
+    Serial.println("Waiting for instructions...");
+}
+
+void outputIncPulse(int nCount) {
+    // INC always starts with HIGH and ends with HIGH
+    int ii;
+    int pulseHalfCycle = 2;  // unit: ms
+    digitalWrite(INC, HIGH);
+    for(ii=0; ii<nCount; ii++) {
+        digitalWrite(INC, LOW);  // Trigger an increment/decrement
+        delay(pulseHalfCycle);
+        digitalWrite(INC, HIGH);
+        delay(pulseHalfCycle);
+    }
+    Serial.print("Output pulse count of "); Serial.println(nCount); // for debugging purpose
+}
+
+void setCap(int nCount, int whichCap) {
+    if (whichCap == 0)
+        digitalWrite(CS0, LOW);
+    else if (whichCap == 1)
+        digitalWrite(CS1, LOW); // Start writing cycle
+    delay(2);
+    digitalWrite(UD, LOW); delay(2); outputIncPulse(34);  // reset to 0
+    digitalWrite(UD, HIGH); delay(2); outputIncPulse(nCount);
+    delay(2);
+    if (whichCap == 0)
+        digitalWrite(CS0, HIGH);  // end writin cycle
+    else if (whichCap == 1)
+        digitalWrite(CS1, HIGH);
+    delay(10);  // storage the write when CS is high and INC is high
+}
+void loop() {
+    int nCount;
+    while (Serial.available() > 0)
+    {
+        char received = Serial.read();
+        inString += received;
+
+        // Process message when new line character is recieved
+        if (received == '\n')
+        {
+            Serial.print("Arduino Received: ");
+            Serial.print(inString);
+            nCount = inString.substring(1).toInt();
+            Serial.print("Capacitance count = "); Serial.println(nCount);
+
+            if (inString.startsWith("A", 0) || inString.startsWith("a", 0) ){
+                Serial.println("Setting Capacitor A");
+                setCap(nCount, 0);
+            }
+            else if (inString.startsWith("B", 0) || inString.startsWith("b", 0) ){
+                Serial.println("Setting Capacitor B");
+                setCap(nCount, 1);
+            }
+            else
+                Serial.println("Unrecognized command");
+
+            inString = ""; // Clear received buffer
+        }
+    }
+}


copied esp apboot to self configure arduino

error: pathspec 'esp-apboot/esp-apboot.ino' did not match any file(s) known to git

--- esp-apboot/esp-apboot.ino
+++ esp-apboot/esp-apboot.ino
@@ -0,0 +1,253 @@
+#include "ESP8266WiFi.h"
+#include <ESP8266mDNS.h>
+#include <WiFiClient.h>
+#include <EEPROM.h>
+
+MDNSResponder mdns;
+WiFiServer server(80);
+
+const char* ssid = "BUBBLES";
+String st;
+
+void setup() {
+  Serial.begin(115200);
+  EEPROM.begin(512);
+  delay(10);
+  Serial.println();
+  Serial.println();
+  Serial.println("Startup");
+  // read eeprom for ssid and pass
+  Serial.println("Reading EEPROM ssid");
+  String esid;
+  for (int i = 0; i < 32; ++i)
+    {
+      esid += char(EEPROM.read(i));
+    }
+  Serial.print("SSID: ");
+  Serial.println(esid);
+  Serial.println("Reading EEPROM pass");
+  String epass = "";
+  for (int i = 32; i < 96; ++i)
+    {
+      epass += char(EEPROM.read(i));
+    }
+  Serial.print("PASS: ");
+  Serial.println(epass);
+  if ( esid.length() > 1 ) {
+      // test esid
+      WiFi.begin(esid.c_str(), epass.c_str());
+      if ( testWifi() == 20 ) {
+          launchWeb(0);
+          return;
+      }
+  }
+  setupAP();
+}
+
+int testWifi(void) {
+  int c = 0;
+  Serial.println("Waiting for Wifi to connect");
+  while ( c < 20 ) {
+    if (WiFi.status() == WL_CONNECTED) { return(20); }
+    delay(500);
+    Serial.print(WiFi.status());
+    c++;
+  }
+  Serial.println("Connect timed out, opening AP");
+  return(10);
+}
+
+void launchWeb(int webtype) {
+          Serial.println("");
+          Serial.println("WiFi connected");
+          Serial.println(WiFi.localIP());
+          Serial.println(WiFi.softAPIP());
+          if (!mdns.begin("esp8266", WiFi.localIP())) {
+            Serial.println("Error setting up MDNS responder!");
+            while(1) {
+              delay(1000);
+            }
+          }
+          Serial.println("mDNS responder started");
+          // Start the server
+          server.begin();
+          Serial.println("Server started");
+          int b = 20;
+          int c = 0;
+          while(b == 20) {
+             b = mdns1(webtype);
+           }
+}
+
+void setupAP(void) {
+
+  WiFi.mode(WIFI_STA);
+  WiFi.disconnect();
+  delay(100);
+  int n = WiFi.scanNetworks();
+  Serial.println("scan done");
+  if (n == 0)
+    Serial.println("no networks found");
+  else
+  {
+    Serial.print(n);
+    Serial.println(" networks found");
+    for (int i = 0; i < n; ++i)
+     {
+      // Print SSID and RSSI for each network found
+      Serial.print(i + 1);
+      Serial.print(": ");
+      Serial.print(WiFi.SSID(i));
+      Serial.print(" (");
+      Serial.print(WiFi.RSSI(i));
+      Serial.print(")");
+      Serial.println((WiFi.encryptionType(i) == ENC_TYPE_NONE)?" ":"*");
+      delay(10);
+     }
+  }
+  Serial.println("");
+  st = "
";
+  for (int i = 0; i < n; ++i)
+    {
+      // Print SSID and RSSI for each network found
+      st += "
";
+      st +=i + 1;
+      st += ": ";
+      st += WiFi.SSID(i);
+      st += " (";
+      st += WiFi.RSSI(i);
+      st += ")";
+      st += (WiFi.encryptionType(i) == ENC_TYPE_NONE)?" ":"*";
+      st += "
";
+    }
+  st += "
";
+  delay(100);
+  WiFi.softAP(ssid);
+  Serial.println("softap");
+  Serial.println("");
+  launchWeb(1);
+  Serial.println("over");
+}
+
+int mdns1(int webtype)
+{
+  // Check for any mDNS queries and send responses
+  mdns.update();
+
+  // Check if a client has connected
+  WiFiClient client = server.available();
+  if (!client) {
+    return(20);
+  }
+  Serial.println("");
+  Serial.println("New client");
+
+  // Wait for data from client to become available
+  while(client.connected() && !client.available()){
+    delay(1);
+   }
+
+  // Read the first line of HTTP request
+  String req = client.readStringUntil('\r');
+
+  // First line of HTTP request looks like "GET /path HTTP/1.1"
+  // Retrieve the "/path" part by finding the spaces
+  int addr_start = req.indexOf(' ');
+  int addr_end = req.indexOf(' ', addr_start + 1);
+  if (addr_start == -1 || addr_end == -1) {
+    Serial.print("Invalid request: ");
+    Serial.println(req);
+    return(20);
+   }
+  req = req.substring(addr_start + 1, addr_end);
+  Serial.print("Request: ");
+  Serial.println(req);
+  client.flush();
+  String s;
+  if ( webtype == 1 ) {
+      if (req == "/")
+      {
+        IPAddress ip = WiFi.softAPIP();
+        String ipStr = String(ip[0]) + '.' + String(ip[1]) + '.' + String(ip[2]) + '.' + String(ip[3]);
+        s = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>\r\nHello from ESP8266 at ";
+        s += ipStr;
+        s += "
";
+        s += st;
+        s += "<form method='get' action='a'>SSID: <input name='ssid' length=32><input name='pass' length=64><input type='submit'></form>";
+        s += "\r\n\r\n";
+        Serial.println("Sending 200");
+      }
+      else if ( req.startsWith("/a?ssid=") ) {
+        // /a?ssid=blahhhh&pass=poooo
+        Serial.println("clearing eeprom");
+        for (int i = 0; i < 96; ++i) { EEPROM.write(i, 0); }
+        String qsid;
+        qsid = req.substring(8,req.indexOf('&'));
+        Serial.println(qsid);
+        Serial.println("");
+        String qpass;
+        qpass = req.substring(req.lastIndexOf('=')+1);
+        Serial.println(qpass);
+        Serial.println("");
+
+        Serial.println("writing eeprom ssid:");
+        for (int i = 0; i < qsid.length(); ++i)
+          {
+            EEPROM.write(i, qsid[i]);
+            Serial.print("Wrote: ");
+            Serial.println(qsid[i]);
+          }
+        Serial.println("writing eeprom pass:");
+        for (int i = 0; i < qpass.length(); ++i)
+          {
+            EEPROM.write(32+i, qpass[i]);
+            Serial.print("Wrote: ");
+            Serial.println(qpass[i]);
+          }
+        EEPROM.commit();
+        s = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>\r\nHello from ESP8266 ";
+        s += "Found ";
+        s += req;
+        s += "
 saved to eeprom... reset to boot into new wifi\r\n\r\n";
+      }
+      else
+      {
+        s = "HTTP/1.1 404 Not Found\r\n\r\n";
+        Serial.println("Sending 404");
+      }
+  }
+  else
+  {
+      if (req == "/")
+      {
+        s = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>\r\nHello from ESP8266";
+        s += "
";
+        s += "\r\n\r\n";
+        Serial.println("Sending 200");
+      }
+      else if ( req.startsWith("/cleareeprom") ) {
+        s = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n\r\n<!DOCTYPE HTML>\r\nHello from ESP8266";
+        s += "
Clearing the EEPROM
";
+        s += "\r\n\r\n";
+        Serial.println("Sending 200");
+        Serial.println("clearing eeprom");
+        for (int i = 0; i < 96; ++i) { EEPROM.write(i, 0); }
+        EEPROM.commit();
+      }
+      else
+      {
+        s = "HTTP/1.1 404 Not Found\r\n\r\n";
+        Serial.println("Sending 404");
+      }
+  }
+  client.print(s);
+  Serial.println("Done with client");
+  return(20);
+}
+
+
+
+void loop() {
+  // put your main code here, to run repeatedly:
+
+}


Adding ArduinoISP example copied from the standard ArduinoISP sample and with the correct RESET pin for the mainboard set.

error: pathspec 'arduino/libraries/BuildingBlocks/examples/ArduinoISP/ArduinoISP.ino' did not match any file(s) known to git

--- arduino/libraries/BuildingBlocks/examples/ArduinoISP/ArduinoISP.ino
+++ arduino/libraries/BuildingBlocks/examples/ArduinoISP/ArduinoISP.ino
@@ -0,0 +1,727 @@
+// This is the same standard ArduinoISP example, with only the RESET pin set to match the one used in the Mainboard module (4).
+
+// ArduinoISP
+// Copyright (c) 2008-2011 Randall Bohn
+// If you require a license, see
+//     http://www.opensource.org/licenses/bsd-license.php
+//
+// This sketch turns the Arduino into a AVRISP
+// using the following arduino pins:
+//
+// Pin 10 is used to reset the target microcontroller.
+//
+// By default, the hardware SPI pins MISO, MOSI and SCK pins are used
+// to communicate with the target. On all Arduinos, these pins can be found
+// on the ICSP/SPI header:
+//
+//               MISO °. . 5V (!) Avoid this pin on Due, Zero...
+//               SCK   . . MOSI
+//                     . . GND
+//
+// On some Arduinos (Uno,...), pins MOSI, MISO and SCK are the same pins
+// as digital pin 11, 12 and 13, respectively. That is why many tutorials
+// instruct you to hook up the target to these pins. If you find this wiring
+// more practical, have a define USE_OLD_STYLE_WIRING. This will work even
+// even when not using an Uno. (On an Uno this is not needed).
+//
+// Alternatively you can use any other digital pin by configuring software ('BitBanged')
+// SPI and having appropriate defines for PIN_MOSI, PIN_MISO and PIN_SCK.
+//
+// IMPORTANT: When using an Arduino that is not 5V tolerant (Due, Zero, ...)
+// as the programmer, make sure to not expose any of the programmer's pins to 5V.
+// A simple way to accomplish this is to power the complete system (programmer
+// and target) at 3V3.
+//
+// Put an LED (with resistor) on the following pins:
+// 9: Heartbeat   - shows the programmer is running
+// 8: Error       - Lights up if something goes wrong (use red if that makes sense)
+// 7: Programming - In communication with the slave
+//
+
+#include "Arduino.h"
+#undef SERIAL
+
+
+#define PROG_FLICKER true
+
+// Configure SPI clock (in Hz).
+// E.g. for an attiny @128 kHz: the datasheet states that both the high
+// and low spi clock pulse must be > 2 cpu cycles, so take 3 cycles i.e.
+// divide target f_cpu by 6:
+//     #define SPI_CLOCK            (128000/6)
+//
+// A clock slow enough for an attiny85 @ 1MHz, is a reasonable default:
+
+#define SPI_CLOCK 		(1000000/6)
+
+
+// Select hardware or software SPI, depending on SPI clock.
+// Currently only for AVR, for other archs (Due, Zero,...),
+// hardware SPI is probably too fast anyway.
+
+#if defined(ARDUINO_ARCH_AVR)
+
+#if SPI_CLOCK > (F_CPU / 128)
+#define USE_HARDWARE_SPI
+#endif
+
+#endif
+
+// Configure which pins to use:
+
+// The standard pin configuration.
+#ifndef ARDUINO_HOODLOADER2
+
+#define RESET     4 // Use BuildingBlocks MainBoard specific pin for reseting the target.
+#define LED_HB    9
+#define LED_ERR   8
+#define LED_PMODE 7
+
+// Uncomment following line to use the old Uno style wiring
+// (using pin 11, 12 and 13 instead of the SPI header) on Leonardo, Due...
+
+// #define USE_OLD_STYLE_WIRING
+
+#ifdef USE_OLD_STYLE_WIRING
+
+#define PIN_MOSI	11
+#define PIN_MISO	12
+#define PIN_SCK		13
+
+#endif
+
+// HOODLOADER2 means running sketches on the atmega16u2
+// serial converter chips on Uno or Mega boards.
+// We must use pins that are broken out:
+#else
+
+#define RESET     	4
+#define LED_HB    	7
+#define LED_ERR   	6
+#define LED_PMODE 	5
+
+#endif
+
+// By default, use hardware SPI pins:
+#ifndef PIN_MOSI
+#define PIN_MOSI 	MOSI
+#endif
+
+#ifndef PIN_MISO
+#define PIN_MISO 	MISO
+#endif
+
+#ifndef PIN_SCK
+#define PIN_SCK 	SCK
+#endif
+
+// Force bitbanged SPI if not using the hardware SPI pins:
+#if (PIN_MISO != MISO) ||  (PIN_MOSI != MOSI) || (PIN_SCK != SCK)
+#undef USE_HARDWARE_SPI
+#endif
+
+
+// Configure the serial port to use.
+//
+// Prefer the USB virtual serial port (aka. native USB port), if the Arduino has one:
+//   - it does not autoreset (except for the magic baud rate of 1200).
+//   - it is more reliable because of USB handshaking.
+//
+// Leonardo and similar have an USB virtual serial port: 'Serial'.
+// Due and Zero have an USB virtual serial port: 'SerialUSB'.
+//
+// On the Due and Zero, 'Serial' can be used too, provided you disable autoreset.
+// To use 'Serial': #define SERIAL Serial
+
+#ifdef SERIAL_PORT_USBVIRTUAL
+#define SERIAL SERIAL_PORT_USBVIRTUAL
+#else
+#define SERIAL Serial
+#endif
+
+
+// Configure the baud rate:
+
+#define BAUDRATE	19200
+// #define BAUDRATE	115200
+// #define BAUDRATE	1000000
+
+
+#define HWVER 2
+#define SWMAJ 1
+#define SWMIN 18
+
+// STK Definitions
+#define STK_OK      0x10
+#define STK_FAILED  0x11
+#define STK_UNKNOWN 0x12
+#define STK_INSYNC  0x14
+#define STK_NOSYNC  0x15
+#define CRC_EOP     0x20 //ok it is a space...
+
+void pulse(int pin, int times);
+
+#ifdef USE_HARDWARE_SPI
+#include "SPI.h"
+#else
+
+#define SPI_MODE0 0x00
+
+class SPISettings {
+public:
+  // clock is in Hz
+  SPISettings(uint32_t clock, uint8_t bitOrder, uint8_t dataMode) : clock(clock){
+    (void) bitOrder;
+    (void) dataMode;
+  };
+
+private:
+  uint32_t clock;
+
+friend class BitBangedSPI;
+};
+
+class BitBangedSPI {
+public:
+  void begin() {
+    digitalWrite(PIN_SCK, LOW);
+    digitalWrite(PIN_MOSI, LOW);
+    pinMode(PIN_SCK, OUTPUT);
+    pinMode(PIN_MOSI, OUTPUT);
+    pinMode(PIN_MISO, INPUT);
+  }
+
+  void beginTransaction(SPISettings settings) {
+    pulseWidth = (500000 + settings.clock - 1) / settings.clock;
+    if (pulseWidth == 0)
+      pulseWidth = 1;
+  }
+
+  void end() {}
+
+  uint8_t transfer (uint8_t b) {
+    for (unsigned int i = 0; i < 8; ++i) {
+      digitalWrite(PIN_MOSI, (b & 0x80) ? HIGH : LOW);
+      digitalWrite(PIN_SCK, HIGH);
+      delayMicroseconds(pulseWidth);
+      b = (b << 1) | digitalRead(PIN_MISO);
+      digitalWrite(PIN_SCK, LOW); // slow pulse
+      delayMicroseconds(pulseWidth);
+    }
+    return b;
+  }
+
+private:
+  unsigned long pulseWidth; // in microseconds
+};
+
+static BitBangedSPI SPI;
+
+#endif
+
+void setup() {
+  SERIAL.begin(BAUDRATE);
+
+  pinMode(LED_PMODE, OUTPUT);
+  pulse(LED_PMODE, 2);
+  pinMode(LED_ERR, OUTPUT);
+  pulse(LED_ERR, 2);
+  pinMode(LED_HB, OUTPUT);
+  pulse(LED_HB, 2);
+
+}
+
+int error = 0;
+int pmode = 0;
+// address for reading and writing, set by 'U' command
+unsigned int here;
+uint8_t buff[256]; // global block storage
+
+#define beget16(addr) (*addr * 256 + *(addr+1) )
+typedef struct param {
+  uint8_t devicecode;
+  uint8_t revision;
+  uint8_t progtype;
+  uint8_t parmode;
+  uint8_t polling;
+  uint8_t selftimed;
+  uint8_t lockbytes;
+  uint8_t fusebytes;
+  uint8_t flashpoll;
+  uint16_t eeprompoll;
+  uint16_t pagesize;
+  uint16_t eepromsize;
+  uint32_t flashsize;
+}
+parameter;
+
+parameter param;
+
+// this provides a heartbeat on pin 9, so you can tell the software is running.
+uint8_t hbval = 128;
+int8_t hbdelta = 8;
+void heartbeat() {
+  static unsigned long last_time = 0;
+  unsigned long now = millis();
+  if ((now - last_time) < 40)
+    return;
+  last_time = now;
+  if (hbval > 192) hbdelta = -hbdelta;
+  if (hbval < 32) hbdelta = -hbdelta;
+  hbval += hbdelta;
+  analogWrite(LED_HB, hbval);
+}
+
+static bool rst_active_high;
+
+void reset_target(bool reset) {
+  digitalWrite(RESET, ((reset && rst_active_high) || (!reset && !rst_active_high)) ? HIGH : LOW);
+}
+
+void loop(void) {
+  // is pmode active?
+  if (pmode) {
+    digitalWrite(LED_PMODE, HIGH);
+  } else {
+    digitalWrite(LED_PMODE, LOW);
+  }
+  // is there an error?
+  if (error) {
+    digitalWrite(LED_ERR, HIGH);
+  } else {
+    digitalWrite(LED_ERR, LOW);
+  }
+
+  // light the heartbeat LED
+  heartbeat();
+  if (SERIAL.available()) {
+    avrisp();
+  }
+}
+
+uint8_t getch() {
+  while (!SERIAL.available());
+  return SERIAL.read();
+}
+void fill(int n) {
+  for (int x = 0; x < n; x++) {
+    buff[x] = getch();
+  }
+}
+
+#define PTIME 30
+void pulse(int pin, int times) {
+  do {
+    digitalWrite(pin, HIGH);
+    delay(PTIME);
+    digitalWrite(pin, LOW);
+    delay(PTIME);
+  } while (times--);
+}
+
+void prog_lamp(int state) {
+  if (PROG_FLICKER) {
+    digitalWrite(LED_PMODE, state);
+  }
+}
+
+uint8_t spi_transaction(uint8_t a, uint8_t b, uint8_t c, uint8_t d) {
+  SPI.transfer(a);
+  SPI.transfer(b);
+  SPI.transfer(c);
+  return SPI.transfer(d);
+}
+
+void empty_reply() {
+  if (CRC_EOP == getch()) {
+    SERIAL.print((char)STK_INSYNC);
+    SERIAL.print((char)STK_OK);
+  } else {
+    error++;
+    SERIAL.print((char)STK_NOSYNC);
+  }
+}
+
+void breply(uint8_t b) {
+  if (CRC_EOP == getch()) {
+    SERIAL.print((char)STK_INSYNC);
+    SERIAL.print((char)b);
+    SERIAL.print((char)STK_OK);
+  } else {
+    error++;
+    SERIAL.print((char)STK_NOSYNC);
+  }
+}
+
+void get_version(uint8_t c) {
+  switch (c) {
+    case 0x80:
+      breply(HWVER);
+      break;
+    case 0x81:
+      breply(SWMAJ);
+      break;
+    case 0x82:
+      breply(SWMIN);
+      break;
+    case 0x93:
+      breply('S'); // serial programmer
+      break;
+    default:
+      breply(0);
+  }
+}
+
+void set_parameters() {
+  // call this after reading paramter packet into buff[]
+  param.devicecode = buff[0];
+  param.revision   = buff[1];
+  param.progtype   = buff[2];
+  param.parmode    = buff[3];
+  param.polling    = buff[4];
+  param.selftimed  = buff[5];
+  param.lockbytes  = buff[6];
+  param.fusebytes  = buff[7];
+  param.flashpoll  = buff[8];
+  // ignore buff[9] (= buff[8])
+  // following are 16 bits (big endian)
+  param.eeprompoll = beget16(&buff[10]);
+  param.pagesize   = beget16(&buff[12]);
+  param.eepromsize = beget16(&buff[14]);
+
+  // 32 bits flashsize (big endian)
+  param.flashsize = buff[16] * 0x01000000
+                    + buff[17] * 0x00010000
+                    + buff[18] * 0x00000100
+                    + buff[19];
+
+  // avr devices have active low reset, at89sx are active high
+  rst_active_high = (param.devicecode >= 0xe0);
+}
+
+void start_pmode() {
+
+  // Reset target before driving PIN_SCK or PIN_MOSI
+
+  // SPI.begin() will configure SS as output,
+  // so SPI master mode is selected.
+  // We have defined RESET as pin 10,
+  // which for many arduino's is not the SS pin.
+  // So we have to configure RESET as output here,
+  // (reset_target() first sets the correct level)
+  reset_target(true);
+  pinMode(RESET, OUTPUT);
+  SPI.begin();
+  SPI.beginTransaction(SPISettings(SPI_CLOCK, MSBFIRST, SPI_MODE0));
+
+  // See avr datasheets, chapter "SERIAL_PRG Programming Algorithm":
+
+  // Pulse RESET after PIN_SCK is low:
+  digitalWrite(PIN_SCK, LOW);
+  delay(20); // discharge PIN_SCK, value arbitrally chosen
+  reset_target(false);
+  // Pulse must be minimum 2 target CPU clock cycles
+  // so 100 usec is ok for CPU speeds above 20KHz
+  delayMicroseconds(100);
+  reset_target(true);
+
+  // Send the enable programming command:
+  delay(50); // datasheet: must be > 20 msec
+  spi_transaction(0xAC, 0x53, 0x00, 0x00);
+  pmode = 1;
+}
+
+void end_pmode() {
+  SPI.end();
+  // We're about to take the target out of reset
+  // so configure SPI pins as input
+  pinMode(PIN_MOSI, INPUT);
+  pinMode(PIN_SCK, INPUT);
+  reset_target(false);
+  pinMode(RESET, INPUT);
+  pmode = 0;
+}
+
+void universal() {
+  uint8_t ch;
+
+  fill(4);
+  ch = spi_transaction(buff[0], buff[1], buff[2], buff[3]);
+  breply(ch);
+}
+
+void flash(uint8_t hilo, unsigned int addr, uint8_t data) {
+  spi_transaction(0x40 + 8 * hilo,
+                  addr >> 8 & 0xFF,
+                  addr & 0xFF,
+                  data);
+}
+void commit(unsigned int addr) {
+  if (PROG_FLICKER) {
+    prog_lamp(LOW);
+  }
+  spi_transaction(0x4C, (addr >> 8) & 0xFF, addr & 0xFF, 0);
+  if (PROG_FLICKER) {
+    delay(PTIME);
+    prog_lamp(HIGH);
+  }
+}
+
+unsigned int current_page() {
+  if (param.pagesize == 32) {
+    return here & 0xFFFFFFF0;
+  }
+  if (param.pagesize == 64) {
+    return here & 0xFFFFFFE0;
+  }
+  if (param.pagesize == 128) {
+    return here & 0xFFFFFFC0;
+  }
+  if (param.pagesize == 256) {
+    return here & 0xFFFFFF80;
+  }
+  return here;
+}
+
+
+void write_flash(int length) {
+  fill(length);
+  if (CRC_EOP == getch()) {
+    SERIAL.print((char) STK_INSYNC);
+    SERIAL.print((char) write_flash_pages(length));
+  } else {
+    error++;
+    SERIAL.print((char) STK_NOSYNC);
+  }
+}
+
+uint8_t write_flash_pages(int length) {
+  int x = 0;
+  unsigned int page = current_page();
+  while (x < length) {
+    if (page != current_page()) {
+      commit(page);
+      page = current_page();
+    }
+    flash(LOW, here, buff[x++]);
+    flash(HIGH, here, buff[x++]);
+    here++;
+  }
+
+  commit(page);
+
+  return STK_OK;
+}
+
+#define EECHUNK (32)
+uint8_t write_eeprom(unsigned int length) {
+  // here is a word address, get the byte address
+  unsigned int start = here * 2;
+  unsigned int remaining = length;
+  if (length > param.eepromsize) {
+    error++;
+    return STK_FAILED;
+  }
+  while (remaining > EECHUNK) {
+    write_eeprom_chunk(start, EECHUNK);
+    start += EECHUNK;
+    remaining -= EECHUNK;
+  }
+  write_eeprom_chunk(start, remaining);
+  return STK_OK;
+}
+// write (length) bytes, (start) is a byte address
+uint8_t write_eeprom_chunk(unsigned int start, unsigned int length) {
+  // this writes byte-by-byte,
+  // page writing may be faster (4 bytes at a time)
+  fill(length);
+  prog_lamp(LOW);
+  for (unsigned int x = 0; x < length; x++) {
+    unsigned int addr = start + x;
+    spi_transaction(0xC0, (addr >> 8) & 0xFF, addr & 0xFF, buff[x]);
+    delay(45);
+  }
+  prog_lamp(HIGH);
+  return STK_OK;
+}
+
+void program_page() {
+  char result = (char) STK_FAILED;
+  unsigned int length = 256 * getch();
+  length += getch();
+  char memtype = getch();
+  // flash memory @here, (length) bytes
+  if (memtype == 'F') {
+    write_flash(length);
+    return;
+  }
+  if (memtype == 'E') {
+    result = (char)write_eeprom(length);
+    if (CRC_EOP == getch()) {
+      SERIAL.print((char) STK_INSYNC);
+      SERIAL.print(result);
+    } else {
+      error++;
+      SERIAL.print((char) STK_NOSYNC);
+    }
+    return;
+  }
+  SERIAL.print((char)STK_FAILED);
+  return;
+}
+
+uint8_t flash_read(uint8_t hilo, unsigned int addr) {
+  return spi_transaction(0x20 + hilo * 8,
+                         (addr >> 8) & 0xFF,
+                         addr & 0xFF,
+                         0);
+}
+
+char flash_read_page(int length) {
+  for (int x = 0; x < length; x += 2) {
+    uint8_t low = flash_read(LOW, here);
+    SERIAL.print((char) low);
+    uint8_t high = flash_read(HIGH, here);
+    SERIAL.print((char) high);
+    here++;
+  }
+  return STK_OK;
+}
+
+char eeprom_read_page(int length) {
+  // here again we have a word address
+  int start = here * 2;
+  for (int x = 0; x < length; x++) {
+    int addr = start + x;
+    uint8_t ee = spi_transaction(0xA0, (addr >> 8) & 0xFF, addr & 0xFF, 0xFF);
+    SERIAL.print((char) ee);
+  }
+  return STK_OK;
+}
+
+void read_page() {
+  char result = (char)STK_FAILED;
+  int length = 256 * getch();
+  length += getch();
+  char memtype = getch();
+  if (CRC_EOP != getch()) {
+    error++;
+    SERIAL.print((char) STK_NOSYNC);
+    return;
+  }
+  SERIAL.print((char) STK_INSYNC);
+  if (memtype == 'F') result = flash_read_page(length);
+  if (memtype == 'E') result = eeprom_read_page(length);
+  SERIAL.print(result);
+}
+
+void read_signature() {
+  if (CRC_EOP != getch()) {
+    error++;
+    SERIAL.print((char) STK_NOSYNC);
+    return;
+  }
+  SERIAL.print((char) STK_INSYNC);
+  uint8_t high = spi_transaction(0x30, 0x00, 0x00, 0x00);
+  SERIAL.print((char) high);
+  uint8_t middle = spi_transaction(0x30, 0x00, 0x01, 0x00);
+  SERIAL.print((char) middle);
+  uint8_t low = spi_transaction(0x30, 0x00, 0x02, 0x00);
+  SERIAL.print((char) low);
+  SERIAL.print((char) STK_OK);
+}
+//////////////////////////////////////////
+//////////////////////////////////////////
+
+
+////////////////////////////////////
+////////////////////////////////////
+void avrisp() {
+  uint8_t ch = getch();
+  switch (ch) {
+    case '0': // signon
+      error = 0;
+      empty_reply();
+      break;
+    case '1':
+      if (getch() == CRC_EOP) {
+        SERIAL.print((char) STK_INSYNC);
+        SERIAL.print("AVR ISP");
+        SERIAL.print((char) STK_OK);
+      }
+      else {
+        error++;
+        SERIAL.print((char) STK_NOSYNC);
+      }
+      break;
+    case 'A':
+      get_version(getch());
+      break;
+    case 'B':
+      fill(20);
+      set_parameters();
+      empty_reply();
+      break;
+    case 'E': // extended parameters - ignore for now
+      fill(5);
+      empty_reply();
+      break;
+    case 'P':
+      if (!pmode)
+        start_pmode();
+      empty_reply();
+      break;
+    case 'U': // set address (word)
+      here = getch();
+      here += 256 * getch();
+      empty_reply();
+      break;
+
+    case 0x60: //STK_PROG_FLASH
+      getch(); // low addr
+      getch(); // high addr
+      empty_reply();
+      break;
+    case 0x61: //STK_PROG_DATA
+      getch(); // data
+      empty_reply();
+      break;
+
+    case 0x64: //STK_PROG_PAGE
+      program_page();
+      break;
+
+    case 0x74: //STK_READ_PAGE 't'
+      read_page();
+      break;
+
+    case 'V': //0x56
+      universal();
+      break;
+    case 'Q': //0x51
+      error = 0;
+      end_pmode();
+      empty_reply();
+      break;
+
+    case 0x75: //STK_READ_SIGN 'u'
+      read_signature();
+      break;
+
+    // expecting a command, not CRC_EOP
+    // this is how we can get back in sync
+    case CRC_EOP:
+      error++;
+      SERIAL.print((char) STK_NOSYNC);
+      break;
+
+    // anything else we will return STK_UNKNOWN
+    default:
+      error++;
+      if (CRC_EOP == getch())
+        SERIAL.print((char)STK_UNKNOWN);
+      else
+        SERIAL.print((char)STK_NOSYNC);
+  }
+}
+


example arduino device client using UDP with encryption

error: pathspec 'src/arduino_iot_cli/arduino_iot_cli.ino' did not match any file(s) known to git

--- src/arduino_iot_cli/arduino_iot_cli.ino
+++ src/arduino_iot_cli/arduino_iot_cli.ino
@@ -0,0 +1,146 @@
+#include <Crypto.h>
+#include <AES.h>
+#include <CBC.h>
+#include <SHA256.h>
+#include <string.h>
+#include <EEPROM.h>
+#include <SPI.h>
+#include <Ethernet.h>
+#include <EthernetUdp.h>
+#include <VirtualWire.h>
+
+const byte receive_pin = 4;
+
+byte mac[] = {  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
+IPAddress myIp(192, 168, 1, 150);
+IPAddress serverIp(192, 168, 1, 134);
+byte deviceId[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
+byte key[]  = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
+
+EthernetUDP Udp;
+CBC<AES256> cbcaes256;
+SHA256 sha256;
+char packet[192];
+byte iv[16];
+byte padded[48];
+long counter = 0;
+char tmp1[10] = {0,0,0,0,0,0,0,0,0,0};
+long tmp1c = 0;
+char tmp2[10] = {0,0,0,0,0,0,0,0,0,0};
+long tmp2c = 0;
+long c = 0;
+
+void setup() {
+  // init radio
+  vw_set_rx_pin(receive_pin);
+  vw_set_ptt_inverted(true); // Required for DR3100
+  vw_setup(2000);   // Bits per sec
+  vw_rx_start();       // Start the receiver PLL running
+
+
+  //init ethernet
+  Ethernet.begin(mac, myIp);
+  Udp.begin(2345);
+
+  Serial.begin(9600);
+
+  //uncomment to reset EEPROM counter
+  //EEPROM.write(0, 0);  EEPROM.write(1, 0);  EEPROM.write(2, 0);  EEPROM.write(3, 0);
+  counter = (long)EEPROM.read(0) + (((long)EEPROM.read(1)) << 8) + (((long)EEPROM.read(2)) << 16) + (((long)EEPROM.read(3)) << 24) + 1;
+}
+
+void loop() {
+    c++;
+    radioReceive();
+    if (c%1000 == 0 && (tmp1[0] != 0 || tmp2[0] != 0)) {
+        if (tmp1[0] !=0 && tmp2[0] == 0)
+        {
+            sprintf((char*)padded, "{\"values\":{\"t1\":%s}}", tmp1);
+        }
+        else if (tmp1[0] ==0 && tmp2[0] != 0)
+        {
+            sprintf((char*)padded, "{\"values\":{\"t2\":%s}}", tmp2);
+        }
+        else
+        {
+            sprintf((char*)padded, "{\"values\":{\"t1\":%s,\"t2\":%s}}", tmp1, tmp2);
+        }
+        Serial.println((char*)padded);
+
+        //encrypt and sign
+        byte srclen = strlen((char*)padded);
+        Serial.println(srclen);
+        byte padnum = 16 - (srclen % 16);
+        //memcpy(padded, payloadStr, strlen(payloadStr));
+        memset(padded+srclen, padnum, padnum);
+
+        int paddedLen = srclen + padnum;
+        Serial.println(paddedLen);
+
+        memset(iv, 0, 16);
+        iv[0] = counter & 0xFF;
+        iv[1] = (counter & 0xFF00) >> 8;
+        iv[3] = (counter & 0xFF0000) >> 16;
+        iv[4] = (counter & 0xFF000000) >> 24;
+        cbcaes256.clear();
+        cbcaes256.setKey(key, 32);
+        cbcaes256.setIV(iv, 16);
+        memcpy(packet, "IOT\0", 4);
+        packet[36] = 1;
+        packet[37] = 1;
+        packet[38] = 0;
+        packet[39] = 0;
+        memcpy(packet+40, deviceId, 16);
+        memcpy(packet+56, iv, 16);
+        cbcaes256.encrypt(((uint8_t*)packet)+72, (uint8_t*)padded, paddedLen);
+        int len = 72+paddedLen;
+        sha256.resetHMAC(key, 32);
+        sha256.update(packet+36, len - 36);
+        sha256.finalizeHMAC(key, 32, packet+4, 32);
+
+        //send
+        Udp.beginPacket(serverIp, 9999);
+        Udp.write(packet, len);
+        Udp.endPacket();
+
+        //store counter in eeprom
+        counter++;
+        if (counter % 10 == 0) {
+            EEPROM.write(0, packet[56]);
+            EEPROM.write(1, packet[57]);
+            EEPROM.write(2, packet[58]);
+            EEPROM.write(3, packet[59]);
+        }
+    }
+
+    delay(10);
+    if (c - tmp1c > 12000){
+        tmp1[0]=0;
+    }
+
+    if (c-tmp2c > 12000) {
+        tmp2[0]=0;
+    }
+}
+
+
+void radioReceive()
+{
+    uint8_t buf[VW_MAX_MESSAGE_LEN];
+    uint8_t buflen = VW_MAX_MESSAGE_LEN;
+    if (vw_get_message(buf, &buflen))
+    {
+        buf[buflen]=0;
+        Serial.println((char*)buf);
+        if ((buflen > 5) && (buflen < 20) && (buf[0] == 'T') && (buf[1] == 'M') && (buf[2] == 'P') && (buf[3] == '1' || buf[3] == '2') && (buf[4] == '='))
+        {
+            if (buf[3] == '1') {
+                memcpy(tmp1, buf+5, buflen-4);
+                tmp1c = c;
+            } else if (buf[3] == '2'){
+                memcpy(tmp2, buf+5, buflen-4);
+                tmp2c = c;
+            }
+        }
+    }
+}


Add motor control arduino sketch

Add motor control arduino sketch

error: pathspec 'steppercontrol/steppercontrol.ino' did not match any file(s) known to git

--- steppercontrol/steppercontrol.ino
+++ steppercontrol/steppercontrol.ino
@@ -0,0 +1,51 @@
+int motorPin = 9;
+int switchPin = 7;
+int motorStep = 0;
+int maxStep = 200;
+int minimumStepDelay = 2;
+
+String motorState = String("off");
+
+void makeStep() {
+  digitalWrite(motorPin, HIGH);
+  digitalWrite(motorPin, LOW);
+  motorStep += 1;
+  if (motorStep > maxStep) {
+    motorStep = 0;
+  }
+}
+
+void resetMotor() {
+  for (int i = motorStep; i < maxStep; i++) {
+    makeStep();
+    delay(minimumStepDelay);
+  }
+}
+
+void setup()  {
+  pinMode(switchPin, INPUT);
+  pinMode(motorPin, OUTPUT);
+  digitalWrite(switchPin, HIGH);
+
+  Serial.begin(9600);
+}
+
+void loop()  {
+  if(Serial.available() > 0) {
+    char command = Serial.read();
+    switch (command) {
+      case 'd':
+        Serial.println(String("Current step: ") + motorStep);
+        break;
+      case 's':
+        makeStep();
+        Serial.println(motorStep);
+        break;
+      case 'r':
+        resetMotor();
+        Serial.println(String("Motor reset. (Step is ") + motorStep + String(")"));
+    }
+  }
+}
+
+


Original version from who93/oak_weathershield

https://github.com/who93/oak_weathershield/commit/d18f22977b5f78f49595f73520097cb781b7ba93

error: pathspec 'oak/oak_weather.ino' did not match any file(s) known to git

--- oak/oak_weather.ino
+++ oak/oak_weather.ino
@@ -0,0 +1,114 @@
+/*Oak Weather Shield sample code
+ * Using SparkFunHTU21D.h library from https://github.com/sparkfun/SparkFun_HTU21D_Breakout_Arduino_Library
+ * Using BMP180_Breakout_Arduino_Library from https://github.com/sparkfun/BMP180_Breakout_Arduino_Library
+ *
+ * Get temperature and humidity from HTU21D, pressure from BMP180 with I2C
+ * Ambient light is read out with PCF8591 ADC on ADC0
+ */
+
+#include <Wire.h>
+#include "SparkFunHTU21D.h"
+#include "SFE_BMP180.h"
+
+HTU21D htu;
+SFE_BMP180 bmp;
+
+#define ALTITUDE 509 //Altitude in meter
+#define PCF8591 (0x90 >> 1) //I2C bus address
+#define ADC0 0x00 //ADC0
+
+int Sleep_pin = 5;   // (Configure as INPUT_PULLUP to default HIGH)
+int OakLEDpin = 1;   // Oak onboard LED pin 1
+int sleepTimeS = 150; // 150 seconds - adjust a needed
+
+float temperature;
+float humidity;
+float pressure;
+int ambient;
+
+void fetchTemperature()
+{
+  temperature = htu.readTemperature();
+}
+
+void fetchHumidity()
+{
+  humidity = htu.readHumidity();
+}
+
+void fetchPressure()
+{
+  char status  = bmp.startTemperature();
+  char buffer[10];
+  double T,P,p0;
+  if (status != 0)
+  {
+    delay(status);
+
+    status = bmp.getTemperature(T);
+    if (status != 0)
+    {
+      status = bmp.startPressure(3);
+      if (status != 0)
+      {
+        delay(status);
+        status = bmp.getPressure(P,T);
+        if (status != 0)
+        {
+          pressure = bmp.sealevel(P,ALTITUDE);
+        }
+        else Particle.publish("error retrieving pressure measurement\n");
+      }
+      else Particle.publish("error starting pressure measurement\n");
+    }
+    else Particle.publish("error retrieving temperature measurement\n");
+  }
+  else Particle.publish("error starting temperature measurement\n");
+}
+
+void printData()
+{
+  char tmpStr[64];
+  sprintf(tmpStr, "weather;%s;%s;%s;%s", String(temperature).c_str(), String(ambient).c_str(), String(pressure).c_str(), String(humidity).c_str());
+  Particle.publish("weatherstation", tmpStr, 60, PRIVATE);
+}
+
+void fetchAmbient()
+{
+  byte value0;
+  Wire.beginTransmission(PCF8591); // wake up PCF8591
+  Wire.write(ADC0); // control byte - read ADC0
+  Wire.endTransmission(); // end tranmission
+  Wire.requestFrom(PCF8591, 2);
+  value0 = Wire.read();
+  value0 = Wire.read();
+  delay(200);
+  ambient = value0;
+}
+
+void setup(void)
+{
+  pinMode(Sleep_pin, INPUT_PULLUP); // Use pullup mode to default HIGH
+
+  htu.begin();
+  if (!bmp.begin())
+  {
+    Particle.publish("Error, bmp not connected!");
+    while (1);
+  }
+  fetchTemperature();
+  fetchHumidity();
+  fetchPressure();
+  fetchAmbient();
+  printData();
+
+  if (digitalRead(Sleep_pin) == HIGH)
+  {
+    ESP.deepSleep(sleepTimeS * 1000000, WAKE_RF_DEFAULT); // Sleep
+  }
+} //END setup()
+
+void loop(void)
+{
+
+}


Added untested receive code for nduino mod

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/ekwoodrich/nirha.git/'


Manufacturer specificies at least 10 microsec to trigger HC-SR04

According to manufacturer's specifications at least 10 microseconds are needed to trigger the chirp of ultrasound used by the HC-SR04.

error: pathspec 'Testing' did not match any file(s) known to git
error: pathspec 'the' did not match any file(s) known to git
error: pathspec 'Board/Test_Ultrasound/Test_Ultrasound.ino' did not match any file(s) known to git


Added raw output to TwitterClient for debugging

--- WiFi/examples/WifiTwitterClient/WifiTwitterClient.ino
+++ WiFi/examples/WifiTwitterClient/WifiTwitterClient.ino
@@ -13,7 +13,7 @@
  Circuit:
  * WiFi shield attached to pins 10, 11, 12, 13

- created 8 Mar 2012
+ created 9 Mar 2012
  by Tom Igoe

  This code is in the public domain.
@@ -71,7 +71,9 @@
     if (client.available()) {
       // read incoming bytes:
       char inChar = client.read();
-
+      // print the incoming byte (for debugging):
+      Serial.write(inChar);
+
       // add incoming byte to end of line:
       currentLine += inChar;

@@ -117,7 +119,8 @@
     Serial.println("making HTTP request...");
     // make HTTP GET request to twitter:
     client.println("GET /1/statuses/user_timeline.xml?screen_name=arduinoteam HTTP/1.1");
-    client.println("HOST:api.twitter.com");
+    client.println("Host:api.twitter.com");
+    client.println("Connection:close");
     client.println();
   }
   // note the time of this connect attempt:
@@ -132,7 +135,7 @@

   // print your WiFi shield's IP address:
   IPAddress ip = WiFi.localIP();
-    Serial.print("IP Address: ");
+  Serial.print("IP Address: ");
   Serial.println(ip);

   // print the received signal strength:
@@ -142,3 +145,4 @@
   Serial.println(" dBm");
 }

+


Ntag216_AUTH.ino own directory

Ntag216_AUTH.ino own directory

error: pathspec 'examples/Ntag216_AUTH/Ntag216_AUTH.ino' did not match any file(s) known to git

--- examples/Ntag216_AUTH/Ntag216_AUTH.ino
+++ examples/Ntag216_AUTH/Ntag216_AUTH.ino
@@ -0,0 +1,59 @@
+//This example show how you can get Authenticated by the NTAG213,215,216 by default the tags are unprotected in order to protect them we need to write 4 different values:
+// Using mfrc522.MIFARE_Ultralight_Write(PageNum, Data, #Databytes))
+//1.- we need to write the 32bit passWord to page 0xE5 !for ntag 213 and 215 page is different refer to nxp documentation!
+//2.- Now Write the 16 bits pACK to the page 0xE6 use the 2 high bytes like this: pACKH + pACKL + 00 + 00 after an authentication the tag will return this secret bytes
+//3.- Now we need to write the first page we want to protect this is a 1 byte data in page 0xE3 we need to write 00 + 00 + 00 + firstPage  all pages after this one are write protected
+// Now WRITE protection is ACTIVATED so we need to get authenticated in order to write the last data
+//4.- Finally we need to write an access record in order to READ protect the card this step is optional only if you want to read protect also write 80 + 00 + 00 + 00 to 0xE4
+//After completeing all these steps you will nee to authentiate first in order to read or write ant page after the first page you selected to protect
+//To disengage proection just write the page (0xE3) to 00 + 00 + 00 + FF that going to remove all protection
+//Made by GARGANTUA from RoboCreators.com & paradoxalabs.com
+
+#include <SPI.h>
+#include <MFRC522.h>
+
+#define RST_PIN    9   //
+#define SS_PIN    10    //
+
+MFRC522 mfrc522(SS_PIN, RST_PIN); // Create MFRC522 instance
+
+void setup() {
+  Serial.begin(9600);   // Initialize serial communications with the PC
+  while (!Serial);    // Do nothing if no serial port is opened (added for Arduinos based on ATMEGA32U4)
+  SPI.begin();      // Init SPI bus
+  mfrc522.PCD_Init();   // Init MFRC522
+  Serial.println(F("Scan PICC to see UID, type, and data blocks..."));
+}
+
+void loop() {
+  // Look for new cards
+  if ( ! mfrc522.PICC_IsNewCardPresent()) {
+    return;
+  }
+
+  // Select one of the cards
+  if ( ! mfrc522.PICC_ReadCardSerial()) {
+    return;
+  }
+
+
+byte PSWBuff[]={0xFF,0xFF,0xFF,0xFF}; //32 bit PassWord default FFFFFFFF
+byte pACK[]={0,0}; //16 bit PassWord ACK returned by the NFCtag
+
+Serial.print("Auth: ");
+Serial.println(mfrc522.PCD_NTAG216_AUTH(&PSWBuff[0],pACK)); //Request Authentification if return STATUS_OK we are good
+
+//Print PassWordACK
+Serial.print(pACK[0],HEX);
+Serial.println(pACK[1],HEX);
+
+byte WBuff[] = {0x00,0x00,0x00,0x04};
+byte RBuff[18];
+
+//Serial.print("CHG BLK: ");
+//Serial.println(mfrc522.MIFARE_Ultralight_Write(0xE3, WBuff, 4));  //How to write to a page
+
+mfrc522.PICC_DumpMifareUltralightToSerial(); //This is a modifier dunp just cghange the for cicle to < 232 instead of < 16 in order to see all the pages on NTAG216
+
+delay(3000);
+}


First prototype sketch

First prototype sketch

error: pathspec 'sensebox/sensebox.ino' did not match any file(s) known to git

--- sensebox/sensebox.ino
+++ sensebox/sensebox.ino
@@ -0,0 +1,258 @@
+#include <SoftwareSerial.h>
+#include <TinyGPS.h>
+#include <SPI.h>
+#include <SD.h>
+#include <Wire.h>
+#include <Digital_Light_TSL2561.h>
+#include "Barometer.h"
+#include "I2Cdev.h"
+#include "MPU6050.h"
+
+const int LED = 7;
+const int chipSelect = 4;
+const int soundSensor = A0;
+
+//Barometer variables
+float pressure;
+float atm;
+float altitude;
+Barometer myBarometer;
+
+//Accelerometer variables
+MPU6050 accelgyro;
+I2Cdev   I2C_M;
+int16_t ax, ay, az;
+int16_t gx, gy, gz;
+int16_t   mx, my, mz;
+float Axyz[3];
+float Gxyz[3];
+float Mxyz[3];
+
+TinyGPS gps;
+
+File dataFile;
+String dataRow;
+String seperator = ",";
+String dattim = "noval";
+int rowCounter = 1;
+
+SoftwareSerial ss(2, 3);
+
+//Button variables
+const int buttonPin = 8;     // the number of the pushbutton pin
+int buttonState = 0;
+int lastButtonState = 0; // variable for reading the pushbutton status
+int isOn;
+
+/*
+  GPS to 3, 2, 5V and GND.
+  Sound to A0.
+  Gyro, Light and Barometer to I2C.
+  Button to 8.
+  LED to 7.
+*/
+
+void setup() {
+  Serial.begin(9600);
+  Wire.begin();
+  //Initialize Accelerometer
+  accelgyro.initialize();
+  Serial.println(accelgyro.testConnection() ? F("MPU6050 connection successful") : F("MPU6050 connection failed"));
+
+  delay(1000);
+
+  // Initialize Light Sensor
+  TSL2561.init();
+
+  //Init barometer
+  myBarometer.init();
+
+
+  // Initalize SD card:
+  //Serial.print("init sd card...");
+
+  if (!SD.begin(chipSelect)) {
+    //Serial.println("Card failed, or not present");
+    // don't do anything more:
+    return;
+  }
+  //Serial.println(F("card initialized."));
+
+  //Pins:
+  pinMode(LED, OUTPUT);
+  pinMode(soundSensor, INPUT);
+  pinMode(buttonPin, INPUT);
+
+  //Serial.println(F(FreeRam()));
+  dataFile = SD.open("test.csv", FILE_WRITE);
+
+  // If the file opened okay, write to it:
+  if (dataFile) {
+    //Serial.print("Writing to test.txt...");
+    dataFile.println("Logging: row, lat, lon, time, sound, brightness, vibration, pressure.");
+    // close the file:
+    dataFile.close();
+    //Serial.println("done.");
+  } else {
+    // if the file didn't open, print an error:
+    Serial.println(F("error opening test.txt"));
+  }
+}
+
+void loop() {
+  buttonState = digitalRead(buttonPin);
+
+  //Serial.println(buttonState);
+  if (buttonState != lastButtonState) {
+    if (buttonState == HIGH) {
+      //buttonPushCounter++;
+      Serial.println(F("ON"));
+      isOn = 1 - isOn;
+      //Serial.print(buttonPushCounter);
+
+    } else {
+      Serial.println(F("OFF"));
+    }
+    delay(50);
+  }
+  lastButtonState = buttonState;
+
+  if (isOn == 1) {
+    digitalWrite(LED, HIGH);
+    bool newData = false;
+
+    ss.begin(9600);
+
+    //Serial.println("starting gps reading");
+
+    // Parse GPS data for one second and report some key values
+    //Serial.println("Searching GPS...");
+    for (unsigned long start = millis(); millis() - start < 1000;)
+    {
+      while (ss.available())
+      {
+        char c = ss.read();
+        //Serial.print(c); // uncomment to see the full NMEA datasets
+        if (gps.encode(c)) { // Did a new valid sentence come in?
+          newData = true;
+          Serial.println(F("Data found! Proceeding..."));
+        }
+      }
+    }
+
+    ss.end();
+
+
+    if (newData)
+
+    {
+      // IF NEW GPS-DATA
+      Serial.println(F("GPS data found!"));
+
+
+
+      float flat, flon;
+      unsigned long age, date, time;
+      gps.f_get_position(&flat, &flon, &age);
+      //Serial.println("");
+      //Serial.print("LAT = ");
+      flat == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : flat, 6;
+      //Serial.print("LON = ");
+      flon == TinyGPS::GPS_INVALID_F_ANGLE ? 0.0 : flon, 6;
+      // Serial.println("DATE & TIME:");
+
+      // print date
+      int year;
+      byte month, day, hour, minute, second, hundredths;
+      gps.crack_datetime(&year, &month, &day, &hour, &minute, &second, &hundredths, &age);
+      if (age == TinyGPS::GPS_INVALID_AGE)
+        Serial.print(F("********** ******** "));
+      else
+      {
+        char sz[32];
+        sprintf(sz, "%02d/%02d/%02d %02d:%02d:%02d ",
+                month, day, year, hour, minute, second);
+        //Serial.print(sz);
+        dattim = String(sz);
+        //Serial.print(dattim);
+      }
+
+      // GPS reading done
+      newData = false;
+
+      //read sensors
+      //reading done directly due to memory limitations
+      //Serial.println("reading sensors");
+
+      //temp and humidity
+
+      //Sound
+      //loudness = analogRead(SOUND_SENSOR);
+
+      //Light
+      //brightness = TSL2561.readVisibleLux();
+
+      //Accel/Gyro
+
+      getAccel_Data();
+      getGyro_Data();
+      //
+      //      Serial.println("Vib index:");
+      //      vib_index = abs(Axyz[0]) + abs(Axyz[1]) + abs(Axyz[2]);
+      //      Serial.println(abs(Axyz[0]) + abs(Axyz[1]) + abs(Axyz[2]));
+
+      //Save collected data to sd card
+      dataFile = SD.open("test.csv", FILE_WRITE);
+
+      if (dataFile) {
+        // Serial.print("Writing to test.txt...");
+        dataFile.print(rowCounter);
+        dataFile.print(seperator);
+        dataFile.print(flat, 6);
+        dataFile.print(seperator);
+        dataFile.print(flon, 6);
+        dataFile.print(seperator);
+        dataFile.print(dattim);
+        dataFile.print(seperator);
+        dataFile.print(analogRead(soundSensor));
+        dataFile.print(seperator);
+        dataFile.print(TSL2561.readVisibleLux());
+        dataFile.print(seperator);
+        dataFile.print((abs(Axyz[0]) + abs(Axyz[1]) + abs(Axyz[2])), 2);
+        dataFile.print(seperator);
+        dataFile.print(myBarometer.calcAltitude(myBarometer.bmp085GetPressure(myBarometer.bmp085ReadUP())));
+
+        // close the file:
+        dataFile.close();
+
+        rowCounter = rowCounter + 1;
+        //Serial.println(F("done writing."));
+      } else {
+        // if the file didn't open, print an error:
+        //Serial.println(F("error opening file"));
+      }
+
+    }
+  } else {
+    digitalWrite(LED, LOW);   // turn the LED on (HIGH is the voltage level)
+  }
+
+}
+
+void getAccel_Data(void)
+{
+  accelgyro.getMotion9(&ax, &ay, &az, &gx, &gy, &gz, &mx, &my, &mz);
+  Axyz[0] = (double) ax / 16384;
+  Axyz[1] = (double) ay / 16384;
+  Axyz[2] = (double) az / 16384;
+}
+
+void getGyro_Data(void)
+{
+  accelgyro.getMotion9(&ax, &ay, &az, &gx, &gy, &gz, &mx, &my, &mz);
+  Gxyz[0] = (double) gx * 250 / 32768;
+  Gxyz[1] = (double) gy * 250 / 32768;
+  Gxyz[2] = (double) gz * 250 / 32768;
+}
+
+


Create compass.ino

Create compass.ino

error: pathspec 'compass.ino' did not match any file(s) known to git

--- compass.ino
+++ compass.ino
@@ -0,0 +1,31 @@
+#include <Wire.h>
+
+#define Addr 0x1E               //  i2c address
+
+void setup() {
+  Serial.begin(9600);
+  delay(100);                   // if you forget this step, your results will be muddled
+  Wire.begin();
+
+  // Set operating mode to continuous
+  Wire.beginTransmission(Addr);
+  Wire.write(byte(0x02));
+  Wire.write(byte(0x00));
+  Wire.endTransmission();
+}
+int compass() {
+  int x, y, z;
+
+  // Initiate communications with compass
+  Wire.beginTransmission(Addr);
+  Wire.write(byte(0x03));       // most significant byte first
+  Wire.endTransmission();
+
+  Wire.requestFrom(Addr, 6);    // request two bytes per axis
+  if(Wire.available() <=6) {    // need  6 bytes available
+    x = Wire.read() << 8 | Wire.read();
+    z = Wire.read() << 8 | Wire.read();
+    y = Wire.read() << 8 | Wire.read();
+  }
+return(x,y,z);
+}


Clean up formatting

Clean up formatting

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/onordbo/mood-cloud.git/'


re-add re-connect in loop. Required for YunHub to reconnect after Mac & Mosquitto restart.

error: pathspec 'projects/YunHub/YunHub_1.07_MQTT/YunHub_1.07_MQTT.ino' did not match any file(s) known to git

--- projects/YunHub/YunHub_1.07_MQTT/YunHub_1.07_MQTT.ino
+++ projects/YunHub/YunHub_1.07_MQTT/YunHub_1.07_MQTT.ino
@@ -0,0 +1,210 @@
+//
+// Receive RFM12B packets and publish to  MQTT server 192.168.178.27
+//
+// only for dedicated senders:
+//
+// 1) Temperature Node (group 33, node 22)
+//      --> time stamp, RF12 group ID, node ID, Vcc, T1, T2
+// 2) RadioBlip2 (group 33, id 17)
+//
+// Blink LED #13 for each package received
+//
+#define PROGRAMVERSION "150919 YunHub 1.07"
+
+#include <Bridge.h>
+#include <JeeLib.h>
+#include <YunClient.h>
+#include <PubSubClient.h>
+
+byte rf12_group, rf12_nodeid;
+String timeStamp, dataStr, rawdataStr;
+char message_buff[100];
+
+// Update these with values suitable for your network.
+byte server[] = { 192, 168, 178, 27 };
+
+
+// Temperature node data structure. Timestamp created locally, at time of receival.
+struct
+{
+  String timeStamp;   // "+%Y-%m-%d %T": format "YYYY-MM-DD hh:mm:ss"
+  byte rf12_group;    // RF12 group ID
+  byte rf12_nodeid;   // RF12 node ID
+  float Vcc;          // Supply voltage
+  float T1;            // Temperature reading
+  float T2;            // Temperature reading
+} TNodeData;
+
+
+// RadioBlip2 data structure. Timestamp created locally, at time of receival.
+struct
+{
+  String timeStamp;   // "+%Y-%m-%d %T": format "YYYY-MM-DD hh:mm:ss"
+  byte rf12_group;    // RF12 group ID
+  byte rf12_nodeid;   // RF12 node ID
+  float Vcc;          // Supply voltage
+} RadioBlip2Data;
+
+
+// ===========================================================
+// MQTT callback function, called for incoming messages
+// ===========================================================
+void callback(char *topic, byte *payload, unsigned int length)
+{
+  // counter
+  int i = 0;
+  // buffer for payload-to-string conversion
+  char message_buff[100];
+
+  // copy payload to buffer, append \0
+  for (i = 0; i < length; i++)
+  {
+    message_buff[i] = payload[i];
+  }
+  message_buff[i] = '\0';
+}
+
+YunClient yun;
+PubSubClient client(server, 1883, callback, yun);
+
+void setup ()
+{
+  // start-up the Yun bridge
+  Bridge.begin();
+  delay(2000);
+
+  Serial.begin(57600);
+  Serial.println("***");
+  Serial.print("*** ");
+  Serial.println(PROGRAMVERSION);
+  Serial.println("***");
+
+  // initialize digital pin 13 as an output.
+  pinMode(13, OUTPUT);
+
+  rf12_initialize(1, RF12_868MHZ, 0); // group id = 0 to receive from all groups
+
+  // Connect to MQTT server if not available
+  client.connect("arduinoYunClient");
+  client.publish("ConnectMessage", "YunChen setup: connected.");
+}
+
+
+void loop ()
+{
+  client.loop();
+
+  if (rf12_recvDone() && rf12_crc == 0)
+  {
+    digitalWrite(13, HIGH);   // turn the LED on (HIGH is the voltage level)
+
+    // Connect to MQTT server if connection was lost
+    if (!client.connected())
+    {
+      client.connect("arduinoYunClient");
+      client.publish("ConnectMessage", "YunChen loop: reconnected.");
+    }
+
+    // identify sender via group & nodeid
+    // node id is in the first 5 bits of rf12_hdr --> & RF12_HDR_MASK
+    rf12_group = rf12_grp;
+    rf12_nodeid = rf12_hdr & RF12_HDR_MASK;
+    timeStamp = getTimeStamp();
+
+
+    ////////////////////////////////////
+    //  Raw Data (group ALL, id ALL)  //
+    ////////////////////////////////////
+
+    /* remove raw data log since it freezes for long data strings
+    rawdataStr = timeStamp + ","
+                 + String(rf12_group) + ","
+                 + String(rf12_nodeid);
+    for (byte i = 0; i < rf12_len; ++i)
+    {
+      rawdataStr += ",";
+      rawdataStr += rf12_data[i];
+    }
+
+    // publish to MQTT server
+    char charBuf[rawdataStr.length()];
+    rawdataStr.toCharArray(charBuf, rawdataStr.length());
+    client.publish("RF12_RawData", charBuf);
+    */
+
+
+    ///////////////////////////////
+    //  TNode (group 33, id 22)  //
+    ///////////////////////////////
+    if (rf12_group == 33 and rf12_nodeid == 22)
+    {
+      TNodeData.rf12_group = rf12_group;
+      TNodeData.rf12_nodeid = rf12_nodeid;
+      TNodeData.timeStamp = timeStamp;
+      TNodeData.Vcc = int(word(rf12_data[1], rf12_data[0])) / 1000.0;
+      TNodeData.T1 = int(word(rf12_data[3], rf12_data[2])) / 100.0;
+      TNodeData.T2 = int(word(rf12_data[5], rf12_data[4])) / 100.0;
+
+      dataStr = TNodeData.timeStamp + ","
+                + String(TNodeData.rf12_group) + ","
+                + String(TNodeData.rf12_nodeid) + ","
+                + String(TNodeData.Vcc) + ","
+                + String(TNodeData.T1) + ","
+                + String(TNodeData.T2);
+
+      // publish interpreted TNode data to MQTT server
+      char charBuf[dataStr.length() + 1];
+      dataStr.toCharArray(charBuf, dataStr.length());
+      client.publish("TNode", charBuf);
+    }
+
+    ////////////////////////////////////
+    //  RadioBlip2 (group 33, id 17)  //
+    ////////////////////////////////////
+    if (rf12_group == 33 and rf12_nodeid == 17)
+    {
+      RadioBlip2Data.rf12_group = rf12_group;
+      RadioBlip2Data.rf12_nodeid = rf12_nodeid;
+      RadioBlip2Data.timeStamp = timeStamp;
+      RadioBlip2Data.Vcc = 1.0 + rf12_data[5] * 0.02;
+
+      dataStr = RadioBlip2Data.timeStamp + ","
+                + String(RadioBlip2Data.rf12_group) + ","
+                + String(RadioBlip2Data.rf12_nodeid) + ","
+                + String(RadioBlip2Data.Vcc);
+
+      // publish interpreted TNode data to MQTT server
+      char charBuf[dataStr.length() + 1];
+      dataStr.toCharArray(charBuf, dataStr.length());
+      client.publish("RadioBlip2", charBuf);
+    }
+    digitalWrite(13, LOW);   // turn the LED off (HIGH is the voltage level)
+  }
+}
+
+
+///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+// This function returns a string with the time stamp
+String getTimeStamp()
+{
+  String result;
+  Process time;
+  // date is a command line utility to get the date and the time
+  // in different formats depending on the additional parameter
+  time.begin("date");
+  time.addParameter("+%Y-%m-%d %T");  // parameters: D for the complete date mm/dd/yy, T for the time hh:mm:ss
+  time.run();  // run the command
+
+  // read the output of the command
+  while (time.available() > 0)
+  {
+    char c = time.read();
+    if (c != '\n')
+      result += c;
+  }
+
+  return result;
+}
+


Added pages to gciTest widgets

Added pages to gciTest widgets

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/TFTLibraries/gciWidget.git/'


stubbed out Arduino INO file for duplexer.

error: pathspec 'firmware/uart_duplexer/uart_duplexer.ino' did not match any file(s) known to git

--- firmware/uart_duplexer/uart_duplexer.ino
+++ firmware/uart_duplexer/uart_duplexer.ino
@@ -0,0 +1 @@
+TODO


Added test application

Added test application

error: pathspec 'src/loraterminal/loraterminal.ino' did not match any file(s) known to git

--- src/loraterminal/loraterminal.ino
+++ src/loraterminal/loraterminal.ino
@@ -0,0 +1,61 @@
+/*
+ * Test application to talk to the RN2483 directly.
+ */
+#include <SoftwareSerial.h>
+
+SoftwareSerial rnSerial(10, 11); // RX, TX
+
+void setup(void) {
+  Serial.begin(9600);
+  rnSerial.begin(9600);
+  autobaud();
+
+  Serial.println("Init done. Type your command and end with the characters \r\n");
+  rnSerial.println("sys get ver");
+  Serial.println(rnSerial.readStringUntil('\n'));
+
+}
+
+/*
+ * Echo bytes back and forth.
+ * Don't forget to send carriage return and newline (yes both) after each command.
+ */
+void loop(void) {
+
+  // Read from RN2483, write to PC
+  if (rnSerial.available()) {
+    Serial.write(rnSerial.read());
+  }
+
+  // Read from PC, write to RN2483
+  if (Serial.available()) {
+    byte b = Serial.read();
+    rnSerial.write(b);
+    Serial.write(b); // echo
+  }
+}
+
+void autobaud()
+{
+  //reset rn2483
+  Serial.print("Reset radio...");
+  pinMode(12, OUTPUT);
+  digitalWrite(12, LOW);
+  delay(500);
+  digitalWrite(12, HIGH);
+  Serial.println("done.");
+
+  String response = "";
+  while (response=="")
+  {
+    delay(1000);
+    Serial.print("autobaud...");
+    rnSerial.write((byte)0x00);
+    rnSerial.write(0x55);
+    rnSerial.println();
+    rnSerial.println("sys get ver");
+    response = rnSerial.readStringUntil('\n');
+    Serial.print(response);
+    Serial.println("*");
+  }
+}


Adding RGB calibration program

Adding RGB calibration program

error: pathspec 'examples/RGBCalibrate/RGBCalibrate.ino' did not match any file(s) known to git

--- examples/RGBCalibrate/RGBCalibrate.ino
+++ examples/RGBCalibrate/RGBCalibrate.ino
@@ -0,0 +1,70 @@
+#include "FastSPI_LED2.h"
+
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+//
+// RGB Calibration code
+//
+// Use this sketch to determine what the RGB ordering for your chipset should be.  Steps for setting up to use:
+//
+// * Uncomment the line in setup that corresponds to the LED chipset that you are using.  (Note that they
+//   all explicitly specify the RGB order as RGB)
+// * Define DATA_PIN to the pin that data is connected to.
+// * (Optional) if using software SPI for chipsets that are SPI based, define CLOCK_PIN to the clock pin
+// * Compile/upload/run the sketch
+//
+// You should see six leds on.  If the RGB ordering is correct, you should see 1 red led, 2 green
+// leds, and 3 blue leds.  If you see different colors, the count of each color tells you what the
+// position for that color in the rgb orering should be.  So, for example, if you see 1 Blue, and 2
+// Red, and 3 Green leds then the rgb ordering should be BRG (Blue, Red, Green).
+//
+// You can then test this ordering by setting the RGB ordering in the addLeds line below to the new ordering
+// and it should come out correctly, 1 red, 2 green, and 3 blue.
+//
+//////////////////////////////////////////////////
+
+#define NUM_LEDS 6
+
+// Data pin that led data will be written out over
+#define DATA_PIN 7
+// Clock pin only needed for SPI based chipsets when not using hardware SPI
+//#define CLOCK_PIN 8
+
+CRGB leds[NUM_LEDS];
+
+void setup() {
+	// sanity check delay - allows reprogramming if accidently blowing power w/leds
+   	delay(2000);
+
+   	// For safety (to prevent too high of a power draw), the test case defaults to
+   	// setting brightness to 25% brightness
+   	LEDS.setBrightness(255);
+
+      // Uncomment one of the following lines for your leds arrangement.
+      // LEDS.addLeds<TM1803, DATA_PIN, RGB>(leds, NUM_LEDS);
+      // LEDS.addLeds<TM1804, DATA_PIN, RGB>(leds, NUM_LEDS);
+      // LEDS.addLeds<TM1809, DATA_PIN, RGB>(leds, NUM_LEDS);
+      // LEDS.addLeds<WS2811, DATA_PIN, RGB>(leds, NUM_LEDS);
+      // LEDS.addLeds<WS2812, DATA_PIN, RGB>(leds, NUM_LEDS);
+      // LEDS.addLeds<WS2812B, DATA_PIN, RGB>(leds, NUM_LEDS);
+      // LEDS.addLeds<UCS1903, DATA_PIN, RGB>(leds, NUM_LEDS);
+
+      // LEDS.addLeds<WS2801, RGB>(leds, NUM_LEDS);
+      // LEDS.addLeds<SM16716, RGB>(leds, NUM_LEDS);
+      // LEDS.addLeds<LPD8806, RGB>(leds, NUM_LEDS);
+
+      // LEDS.addLeds<WS2801, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS);
+      // LEDS.addLeds<SM16716, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS);
+      // LEDS.addLeds<LPD8806, DATA_PIN, CLOCK_PIN, RGB>(leds, NUM_LEDS);
+}
+
+void loop() {
+   leds[0] = CRGB::Red;
+   leds[1] = CRGB::Green;
+   leds[2] = CRGB::Green;
+   leds[3] = CRGB::Blue;
+   leds[4] = CRGB::Blue;
+   leds[5] = CRGB::Blue;
+   LEDS.show();
+   delay(1000);
+}


added basic WiFi manager

added basic WiFi manager

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/werar/iothome.git/'


This is the start of the physical controlls for the score board.

error: pathspec 'physical-user-controlls/player_controls/player_controls.ino' did not match any file(s) known to git

--- physical-user-controlls/player_controls/player_controls.ino
+++ physical-user-controlls/player_controls/player_controls.ino
@@ -0,0 +1,193 @@
+/*
+  MKR1000 WiFi RTC
+
+  This sketch asks NTP for the Linux epoch and sets the internal Arduino MKR1000's RTC accordingly.
+
+  created 08 Jan 2016
+  by Arturo Guadalupi <a.guadalupi@arduino.cc>
+
+  http://arduino.cc/en/Tutorial/WiFiRTC
+  This code is in the public domain.
+*/
+
+#include <SPI.h>
+#include <WiFi101.h>
+#include <WiFiUdp.h>
+#include <RTCZero.h>
+
+RTCZero rtc;
+
+char ssid[] = "beto-land-0";     //  your network SSID (name)
+char pass[] = "fart5noodle";   // your network password
+int keyIndex = 0;            // your network key Index number (needed only for WEP)
+
+int status = WL_IDLE_STATUS;
+
+// Used for NTP
+unsigned int localPort = 2390;      // local port to listen for UDP packets
+IPAddress timeServer(129, 6, 15, 28); // time.nist.gov NTP server
+const int NTP_PACKET_SIZE = 48; // NTP time stamp is in the first 48 bytes of the message
+byte packetBuffer[ NTP_PACKET_SIZE]; //buffer to hold incoming and outgoing packets
+WiFiUDP Udp; // A UDP instance to let us send and receive packets over UDP
+
+const int GMT = 1; //change this to adapt it to your time zone
+
+void setup() {
+  Serial.begin(115200);
+
+  // check if the WiFi module works
+  if (WiFi.status() == WL_NO_SHIELD) {
+    Serial.println("WiFi shield not present");
+    // don't continue:
+    while (true);
+  }
+
+  // attempt to connect to WiFi network:
+  while ( status != WL_CONNECTED) {
+    Serial.print("Attempting to connect to SSID: ");
+    Serial.println(ssid);
+    // Connect to WPA/WPA2 network. Change this line if using open or WEP network:
+    status = WiFi.begin(ssid, pass);
+
+    // wait 10 seconds for connection:
+    delay(10000);
+  }
+
+  // you're connected now, so print out the status:
+  printWifiStatus();
+
+  rtc.begin();
+
+  unsigned long epoch;
+  int numberOfTries = 0, maxTries = 6;
+  do {
+    epoch = readLinuxEpochUsingNTP();
+    numberOfTries++;
+  }
+  while ((epoch == 0) || (numberOfTries > maxTries));
+
+  if (numberOfTries > maxTries) {
+    Serial.print("NTP unreachable!!");
+    while (1);
+  }
+  else {
+    Serial.print("Epoch received: ");
+    Serial.println(epoch);
+    rtc.setEpoch(epoch);
+
+    Serial.println();
+  }
+}
+
+void loop() {
+  printDate();
+  printTime();
+  Serial.println();
+  delay(1000);
+}
+
+unsigned long readLinuxEpochUsingNTP()
+{
+  Udp.begin(localPort);
+  sendNTPpacket(timeServer); // send an NTP packet to a time server
+  // wait to see if a reply is available
+  delay(1000);
+
+  if ( Udp.parsePacket() ) {
+    Serial.println("NTP time received");
+    // We've received a packet, read the data from it
+    Udp.read(packetBuffer, NTP_PACKET_SIZE); // read the packet into the buffer
+
+    //the timestamp starts at byte 40 of the received packet and is four bytes,
+    // or two words, long. First, esxtract the two words:
+
+    unsigned long highWord = word(packetBuffer[40], packetBuffer[41]);
+    unsigned long lowWord = word(packetBuffer[42], packetBuffer[43]);
+    // combine the four bytes (two words) into a long integer
+    // this is NTP time (seconds since Jan 1 1900):
+    unsigned long secsSince1900 = highWord << 16 | lowWord;
+
+    // now convert NTP time into everyday time:
+    // Unix time starts on Jan 1 1970. In seconds, that's 2208988800:
+    const unsigned long seventyYears = 2208988800UL;
+    // subtract seventy years:
+
+    Udp.stop();
+    return (secsSince1900 - seventyYears);
+  }
+
+  else {
+    Udp.stop();
+    return 0;
+  }
+}
+
+void printTime()
+{
+  print2digits(rtc.getHours());
+  Serial.print(":");
+  print2digits(rtc.getMinutes());
+  Serial.print(":");
+  print2digits(rtc.getSeconds());
+  Serial.println();
+}
+
+void printDate()
+{
+  Serial.print(rtc.getDay());
+  Serial.print("/");
+  Serial.print(rtc.getMonth());
+  Serial.print("/");
+  Serial.print(rtc.getYear());
+
+  Serial.print(" ");
+}
+
+// send an NTP request to the time server at the given address
+unsigned long sendNTPpacket(IPAddress & address)
+{
+  // set all bytes in the buffer to 0
+  memset(packetBuffer, 0, NTP_PACKET_SIZE);
+  // Initialize values needed to form NTP request
+  // (see URL above for details on the packets)
+
+  packetBuffer[0] = 0b11100011;   // LI, Version, Mode
+  packetBuffer[1] = 0;     // Stratum, or type of clock
+  packetBuffer[2] = 6;     // Polling Interval
+  packetBuffer[3] = 0xEC;  // Peer Clock Precision
+  // 8 bytes of zero for Root Delay & Root Dispersion
+  packetBuffer[12]  = 49;
+  packetBuffer[13]  = 0x4E;
+  packetBuffer[14]  = 49;
+  packetBuffer[15]  = 52;
+
+  // all NTP fields have been given values, now
+  // you can send a packet requesting a timestamp:
+  Udp.beginPacket(address, 123); //NTP requests are to port 123
+  Udp.write(packetBuffer, NTP_PACKET_SIZE);
+  Udp.endPacket();
+}
+
+void printWifiStatus() {
+  // print the SSID of the network you're attached to:
+  Serial.print("SSID: ");
+  Serial.println(WiFi.SSID());
+
+  // print your WiFi shield's IP address:
+  IPAddress ip = WiFi.localIP();
+  Serial.print("IP Address: ");
+  Serial.println(ip);
+
+  // print the received signal strength:
+  long rssi = WiFi.RSSI();
+  Serial.print("signal strength (RSSI):");
+  Serial.print(rssi);
+  Serial.println(" dBm");
+}
+
+void print2digits(int number) {
+  if (number < 10) {
+    Serial.print("0");
+  }
+  Serial.print(number);
+}


Added state initialization detection to hmac.sha1.update and hmac.sha1.final

Signed-off-by: Edi Permadi <163b49ac0c44ca5b49677bf42f3f8680b3bd9867@gmail.com>

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/edipermadi/teensy-hsm.git/'


Finally updates energy arduino code to current protocol.

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/bassjansson/vera.git/'


Fixed audio routine

Fixed audio routine

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/TFTLibraries/TFT.git/'


External Button example

External Button example

error: pathspec 'examples/_1030_ExternalButton/_1030_ExternalButton.ino' did not match any file(s) known to git

--- examples/_1030_ExternalButton/_1030_ExternalButton.ino
+++ examples/_1030_ExternalButton/_1030_ExternalButton.ino
@@ -0,0 +1,28 @@
+#include <ESPert.h>
+
+ESPert espert;
+bool currentSwitch = true;
+
+ESPert_Button button;
+
+void setup() {
+  espert.init();
+  button.init( 15 );
+  espert.println("Press USER button to turn on LED.");
+}
+
+void loop() {
+  bool buttonPressed = button.isOn();
+
+  if (buttonPressed != currentSwitch) {
+    if (buttonPressed) {
+      espert.println("Button: On");
+      espert.led.on();
+    } else {
+      espert.println("Button: Off");
+      espert.led.off();
+    }
+
+    currentSwitch = buttonPressed;
+  }
+}


Make basic sketch match the more common case of 30 LEDs (as opposed to 60)

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/stevenpetryk/rustle.git/'


Trying to get strncpy() working

Trying to get strncpy() working

remote: Support for password authentication was removed on August 13, 2021.
remote: Please see https://docs.github.com/en/get-started/getting-started-with-git/about-remote-repositories#cloning-with-https-urls for information on currently recommended modes of authentication.
fatal: Authentication failed for 'https://github.com/snowdenator/ESP8266_Stuff.git/'