Однопроводная ШИНА W-BAS

ilsmolencev
Offline
Зарегистрирован: 31.01.2012

Добрый день.

Мне надо послать на ногу сигналы 

01111001011100010000011101000101101100101000001101 0101000111010100001111
 

Один логический ноль или единица = один период (1Т) = 0.415 милисекунд.

Я сделал по простому:

int dataPin = 8;
void setup() {
  pinMode(dataPin, OUTPUT);
  digitalWrite(dataPin, HIGH);
}
void loop() {
   digitalWrite(dataPin, LOW);   delay(1);
      digitalWrite(dataPin, HIGH);   delay(1);
         digitalWrite(dataPin, HIGH);   delay(1);
   digitalWrite(dataPin, HIGH);   delay(1);
      digitalWrite(dataPin, HIGH);delay(1);
     digitalWrite(dataPin, LOW);delay(1);
     digitalWrite(dataPin, LOW);delay(1);
     digitalWrite(dataPin, HIGH);delay(1);
     digitalWrite(dataPin, LOW);delay(1);
     digitalWrite(dataPin, HIGH);delay(1);
     digitalWrite(dataPin, HIGH);delay(1);     
      digitalWrite(dataPin, HIGH);delay(1);
      digitalWrite(dataPin, LOW);delay(1);
      digitalWrite(dataPin, LOW);delay(1);
      digitalWrite(dataPin, LOW);delay(1);
      digitalWrite(dataPin, HIGH);delay(1);
      digitalWrite(dataPin, LOW);delay(1);
      digitalWrite(dataPin, LOW);delay(1);
      digitalWrite(dataPin, LOW);delay(1);
      digitalWrite(dataPin, LOW);delay(1);
      digitalWrite(dataPin, LOW);delay(1);
      digitalWrite(dataPin, HIGH);delay(1);
      digitalWrite(dataPin, HIGH);delay(1);
      digitalWrite(dataPin, HIGH);delay(1);
      digitalWrite(dataPin, LOW);delay(1);
      digitalWrite(dataPin, HIGH);delay(1);
      digitalWrite(dataPin, LOW);delay(1);
      digitalWrite(dataPin, LOW);delay(1);
      digitalWrite(dataPin, LOW);delay(1);
      digitalWrite(dataPin, HIGH);delay(1);
      digitalWrite(dataPin, LOW);delay(1);
      digitalWrite(dataPin, HIGH);delay(1);
      digitalWrite(dataPin, HIGH);delay(1);
      digitalWrite(dataPin, LOW);delay(1);
      digitalWrite(dataPin, HIGH);delay(1);
      digitalWrite(dataPin, HIGH);delay(1);
      digitalWrite(dataPin, LOW);delay(1);
      digitalWrite(dataPin, LOW);delay(1);
      digitalWrite(dataPin, HIGH);delay(1);
      digitalWrite(dataPin, LOW);delay(1);
      digitalWrite(dataPin, HIGH);delay(1);
      digitalWrite(dataPin, LOW);delay(1);
      digitalWrite(dataPin, LOW);delay(1);
      digitalWrite(dataPin, LOW);delay(1);
      digitalWrite(dataPin, LOW);delay(1);
      digitalWrite(dataPin, LOW);delay(1);
      digitalWrite(dataPin, HIGH);delay(1);
      digitalWrite(dataPin, HIGH);delay(1);
      digitalWrite(dataPin, LOW);delay(1);
      digitalWrite(dataPin, HIGH);delay(1);
      digitalWrite(dataPin, LOW);delay(1);
      digitalWrite(dataPin, HIGH);delay(1);
      digitalWrite(dataPin, LOW);delay(1);
      digitalWrite(dataPin, HIGH);delay(1);
      digitalWrite(dataPin, LOW);delay(1);
      digitalWrite(dataPin, LOW);delay(1);
      digitalWrite(dataPin, LOW);delay(1);
      digitalWrite(dataPin, HIGH);delay(1);
      digitalWrite(dataPin, HIGH);delay(1);
      digitalWrite(dataPin, HIGH);delay(1);
      digitalWrite(dataPin, LOW);delay(1);
      digitalWrite(dataPin, HIGH);delay(1);
      digitalWrite(dataPin, LOW);delay(1);
      digitalWrite(dataPin, HIGH);delay(1);
      digitalWrite(dataPin, LOW);delay(1);
      digitalWrite(dataPin, LOW);delay(1);
      digitalWrite(dataPin, LOW);delay(1);
      digitalWrite(dataPin, LOW);delay(1);
      digitalWrite(dataPin, HIGH);delay(1);
      digitalWrite(dataPin, HIGH);delay(1);
      digitalWrite(dataPin, HIGH);delay(1);
      digitalWrite(dataPin, HIGH);delay(1);
               delay(100000);
   
  
}

Но в этом случае у меня выходит один период 0,625.

Если я убераю  delay(1); то сигналы вообще проподают и я не могу их увидеть осцылографом.

Подскажите как можно этого добиться. Может быть использованием таймера или еще как?

спасибо

step962
Offline
Зарегистрирован: 23.05.2011

 

Цитата:

Но в этом случае у меня выходит один период 0,625.

Поделитесь секретом - как у вас при задержке в 1 миллисекунду получается период 0,625 мсек?

 

Перейдите с delay() на delayMicroseconds() - может быть, результат вам больше понравится.

а еще лучше - заведите последовательность в строку и сканируя ее, последовательно выводите сигнал:

char codeSequence="1110101000110001010001001111010";
int msDelay=500;
int i;

i=0;
while(codeSequence[i]!='\0') {
  if(codeSequence[i]=="0") digitalWrite(dataPin,LOW);
  else digitalWrite(dataPin,HIGH);
  delayMicroseconds(msDelay);
  i++;
}

Получится намного короче, хоть и ненамного сложнее.

ilsmolencev
Offline
Зарегистрирован: 31.01.2012

На осцылограмме взял границы времени и поделил на коичество цыклов и получилось 0,625 

ilsmolencev
Offline
Зарегистрирован: 31.01.2012

Спасибо большое использовал delayMicroseconds(msDelay);

И все получилось!! 

step962
Offline
Зарегистрирован: 23.05.2011

ilsmolencev пишет:

На осцылограмме взял границы времени и поделил на коичество цыклов и получилось 0,625 

Вы что-то неправильно делаете - ну не может при длительности импульса в 1 мсек получаться период менее 1 мсек.

Хотя, если система заработала, это уже не так важно.

ilsmolencev
Offline
Зарегистрирован: 31.01.2012

 А можно полный скреч для char codeSequence="1110101000110001010001001111010";

void setup() {
}
void loop() {
}
 

 

step962
Offline
Зарегистрирован: 23.05.2011

 А самому осилить?

Определения переменных поставьте в начало, setup() оставьте без изменений, приведенные ранее инструкции  - в loop(), в конце loop'а воткните свою сколькототамсекундную задержку.

То, что получится, выкладывайте в ветку - так и быть, покритикую. 

ilsmolencev
Offline
Зарегистрирован: 31.01.2012
int dataPin = 8;
int msDelay=207;
char codeSequence;
int i;
void setup() {
  pinMode(dataPin, OUTPUT);
  digitalWrite(dataPin, HIGH);
  codeSequence='1110101000110001010001001111010';
}
void loop() {
    i=0;
   while( codeSequence[i] != '\0') {
  if(codeSequence[i]=="0") digitalWrite(dataPin,LOW);
  else digitalWrite(dataPin,HIGH);
  delayMicroseconds(msDelay);
  i++;
}    
}

Вот что сдалал выдает ошибку на строке  while( codeSequence[i] != '\0') {

LEVV2006
LEVV2006 аватар
Offline
Зарегистрирован: 15.04.2011

Может я не прав. Не очень селён в крутом написании кода. У меня компилируется так.

int dataPin = 8;
int msDelay=207;
int codeSequence[]={1,1,1,0,1,0,1,0,0,0,1,1,0,0,0,1,0,1,0,0,0,1,0,0,1,1,1,1,0,1,0,2};
int i;
void setup() {
  pinMode(dataPin, OUTPUT);
  digitalWrite(dataPin, HIGH);
}
void loop() {
  i=0;
  while( codeSequence[i] != 2) 
  {
    if(codeSequence[i]==0) digitalWrite(dataPin,LOW);
    else digitalWrite(dataPin,HIGH);
    delayMicroseconds(msDelay);
    i++;
  }    
}

 

step962
Offline
Зарегистрирован: 23.05.2011

 А у меня так:

int dataPin = 8;
int msDelay=207;
char codeSequence[]="1110101000110001010001001111010";
int i;
void setup() {
  pinMode(dataPin, OUTPUT);
  digitalWrite(dataPin, HIGH);
}
void loop() {
  i=0;
  while( codeSequence[i] != '\0') {
    if(codeSequence[i]=='0') digitalWrite(dataPin,LOW);
    else digitalWrite(dataPin,HIGH);
    delayMicroseconds(msDelay);
    i++;
  }    
}

Ошибки были сделаны не в той строке, а раньше.

1) Переменная codeSequence была объявлена типа char, т.е. один (!) символ. Изменяем декларацию на

char codeSequence[], т.е. МАССИВ символов. И тут же выполняем инициализацию этой переменной нашим значением. Конечно, присвоение переменной значения можно выполнить и в другом месте скетча - в той же процедуре setup(). Однако в этом случае потребуется ЗАРАНЕЕ определить размер массива, указав в квадратных скобках число, на единицу большее количества символов в нашей строке (дополнительное место под символ конца строки '\0'). А для этого необходимо ручками подсчитать длину строки, а программист, как правило, существо довольно ленивое, предпочитающее, чтобы всю его работу выполнял кто-то другой, например, компилятор.

Можно было бы определить длину массива с запасом (например codeSequence[100]), но в условиях весьма скромного запаса оперативной памяти в микроконтроллерах к этому привыкать не стоит.

 

Цитата:

int codeSequence[]={1,1,1,0,1,0,1,0,0,0,1,1,0,0,0,1,0,1,0,0,0,1,0,0,1,1,1,1,0,1,0,2};

Конечно, можно объявить и массив типа int, но, во-первых, придется использовать не очень удобную инициализацию (вводить дополнительно кучу запятых, а ведь программист, как мы помним ...). Во-вторых, в отличие от char, каждый элемент типа int занимает целых два байта весьма ограниченной оперативной памяти, а нам необходимо ее беречь.

 Еще одно замечание - по поводу правил оформления строк и символов в Си:

Цитата:

char codeSequence[]="1110101000110001010001001111010";

if(codeSequence[i]=='0') digitalWrite(dataPin,LOW);

Символы обрамляем в одинарные кавычки, строки - в двойные. (тут я сам маху дал, в одном месте заключив символ в двойные кавычки)

PS: Еще один призыв в заключение - не пренебрегайте отступами при написании кода. Сдвигайте каждый вложенный блок (в Си это как правило, код, обрамленный фигурными скобками) на несколько позиций вправо (например, на 2). Это помогает быстрее разобраться в структуре программы другим, да и вам в дальнейшем позволит быстрее вспоминать, что и где происходит.

ilsmolencev
Offline
Зарегистрирован: 31.01.2012

Всем спасибо буду пробывать.

Как закончу выложу окончательный вариант.