3

I need to reproduce with a digital pin of an Arduino such a key in the form of a sequence of 1's and 0's, where a one takes 2 ms high and 2 ms low, and a zero takes 1 ms high and 1 ms low. enter image description here

  int key = 0b101100001111;

void setup()
{
  pinMode(13, OUTPUT);
}

void loop()
{
  for (int n = 0; n < 12; n++)
  {
    if (bitRead(key, n) == 1) //execute if bit value == 1
    {
      sendSignal(2000);
    }

    else //execute if bit value == 0
    {
      sendSignal(1000);
    }
  }
}

void sendSignal(int duration)
{
  digitalWrite(13, HIGH);
  delayMicroseconds(duration);
  digitalWrite(13, LOW);
  delayMicroseconds(duration);
}

   

This sketch really works! I figured out what my problem is: I actually need a longer key (64 bits). I am using long type: long key = 0b1000011110001101111100011111001010110001101101111011011100110100; but long only allows 32 bits. What do you recommend to do? Maybe you need to arrange it as an array? I think you can make it easier somehow. thank you

7
  • 4
    0b101100001111 can never fit into a byte. – Majenko Nov 16 '20 at 11:21
  • 1
    That new version of the code you posted works for me, no warnings. Which Arduino are you compiling for? – ocrdu Nov 16 '20 at 14:53
  • 1
    Not visually, because the delayMicroseconds() is too short for the human eye. My oscilloscope shows the right signal. If you want to check visually, replace delayMicroseconds() with delay(). – ocrdu Nov 16 '20 at 15:33
  • 1
    Thanks you! This sketch really works! I realized what my problem is: in fact, I need a longer key (64 bits). I am using long type: long key = 0b1000011110001101111100011111001010110001101101111011011100110100; But long only allows 32 bits. What do you recommend to do? Maybe you need to arrange it as an array? I think you can make it somehow easier. Thank you – Антон Nov 17 '20 at 12:48
  • 1
    There's always an uint64_t to try, on many machines aka long long int. – ocrdu Nov 17 '20 at 14:24
2

You should make

byte key = 0b101100001111;

global, i.e. put it BEFORE the setup function and not within it.

Also, a byte only can contain 8 bits, you need 12, so make it an int (thanks to ocrdu, see comment below):

int key = 0b101100001111;

If you need more bits, you can use uint32_t or uint64_t, and count further than the current 12.

Now key is a local variable which is removed after exiting the setup function.

I'm not sure where 'key' comes from in:

switch (bitRead(key, n)) {

Do you get a compiler error, or did you ALSO define a global variable named key ? Anyway, if you make key global it will fix either way.

A few other remarks:

  • Try to align your parenthesis, like the 3 }'s at the end, indent them properly, this makes your code much more readable
  • Instead of the switch/case, you could use an if statement in this case, as the re are only (and always) two possible values (0 and 1):

Thus:

 if(bitRead(key, n) == 0)
 {
     ...
 } 
 else // 1
 {
     ...
 }
  • Try also comments to write in English instead of Greek, you never know when your comments will be read by non Greek readers (like now).

  • You can make the following fragment shorter and less duplicated:

Original:

digitalWrite(13, HIGH);
delayMicroseconds(1000);
digitalWrite(13, LOW);
delayMicroseconds(1000);

If you wrap this in a function:

void sendSignal(int duration)
{
    digitalWrite(13, HIGH);
    delayMicroseconds(duration);
    digitalWrite(13, LOW);
    delayMicroseconds(duration);
}

Then you can write a 1 by calling:

sendSignal(2000);

and a 0 by calling:

sendSignal(1000);
8
  • It's Russian, not Greek. Just saying 8-). – ocrdu Nov 16 '20 at 9:57
  • @orcdu thanks :-) – Michel Keijzers Nov 16 '20 at 11:15
  • Thank you very much! Really good advice! Did this, it seems like the sketch is without errors and it is loaded into the board. But I cannot track these impulses on an oscilloscope. I tried to change the duration of the impulses by a few seconds, but I don't see the banal blinking of the LED on the 13th pin with my eye, it is always on. I don't understand what's wrong, everything seems to be logical in the sketch – Антон Nov 16 '20 at 12:11
  • 2
    int key, not byte key. 12 bits won't fit. – ocrdu Nov 16 '20 at 13:12
  • @ocrdu good point, I will update my answer – Michel Keijzers Nov 16 '20 at 15:23
2

If you modify the code slightly, you can use an array of characters of any length, so need to worry about digital word length.

Here's a modified version of your program that does this.

Note that I also took the liberty of replacing the 'magic number' 13 with LED_PIN, and the 'magic number' 12 with KEY_LEN. I would suggest you do the same with your pulsewidth values - maybe something like PULSE_WIDTH_ONE_USEC and PULSE_WIDTH_ZERO_USEC? That way someone else (or you 3 months later) looking at your code can easily see what the values are intended to do

const int KEY_LEN = 62;
const char key[KEY_LEN] = { "10110110110101111001011010110100101011011100110110101101101100" };
const int LED_PIN = 13;

//int key = 0b101100001111;
void setup()
{
  Serial.begin(115200);
  pinMode(13, OUTPUT);
}

void loop()
{
  for (int n = 0; n < KEY_LEN; n++)
  {
    if (key[n]== '1') //execute if bit value == 1
    {
      Serial.print("1");
      sendSignal(200);
    }

    else if (key[n] == '0')//execute if bit value == 0
    {
      Serial.print("0");
      sendSignal(100);
    }
    else
    {
      Serial.print("x");
    }
  }
  Serial.println();
}

void sendSignal(int duration)
{
  digitalWrite(LED_PIN, HIGH);
  //delayMicroseconds(duration);
  delay(duration);
  digitalWrite(LED_PIN, LOW);
  //delayMicroseconds(duration);
  delay(duration);
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.