Вывод на LCD 16х2

LumbaLumba
Offline
Зарегистрирован: 18.07.2013

Всем привет!

Прошу помочь ламеру с логикой :)

Факи читал, с простым выводом все понятно.

Есть LCD 16x2, ШД (1.8градусов), есть 3 (A,B,C) кнопки.

Как это работает:

На LCD показаны градусы поворота

200 шагов = 360 градусов

100 = 180

50 = 90

и т д (задаются в ручную)

Кнопками В и С (вперед - назад) прощелкиваются варианты на LCD (360-180-90) по кругу.

При нажатии на кнопку А осущвествляется поворот на то количество градусов (шагов), что указаны на LCD

Вот собственно и все. Не могли бы вы помочь и рассказать как правильно реализовать данную задачу( с небольшим примером - если не сложно)

Спасибо!

maksim
Offline
Зарегистрирован: 12.02.2012

Код покажите. Вставка программного кода в тему/комментарий или как и куда у вас все подключено распишите.

#include <AccelStepper.h>
#include <LiquidCrystal.h>

#define button_A A0
#define button_B A1
#define button_C A2

LiquidCrystal lcd(12, 11, 10, 9, 8, 7);
AccelStepper stepper; // Defaults to 4 pins on 2, 3, 4, 5


int angles[3] = {360, 180, 90};
int angle = 0;
void setup() 
{ 
  digitalWrite(button_A, 1);
  digitalWrite(button_B, 1);
  digitalWrite(button_C, 1);
  stepper.setMaxSpeed(400.0);
  stepper.setAcceleration(1000.0);
  stepper.moveTo(angles[angle]);
  lcd.begin(16, 2);
  lcd.print("Angle: ");
}

void loop() 
{

  if(!digitalRead(button_B)) 
  {
    angle++;
    if(angle == 3) angle = 0;
    delay(200);
  }

  if(!digitalRead(button_C)) 
  {
    angle--;
    if(angle == -1) angle = 2;
    delay(200);
  }

  static int anglePrev;
  if(angle != anglePrev)
  {
    lcd.setCursor(7, 0);
    lcd.print(angles[angle]);
    anglePrev = angle;
  }

  if(!digitalRead(button_A)) stepper.moveTo(angles[angle]);
  stepper.run();
}

 

LumbaLumba
Offline
Зарегистрирован: 18.07.2013
#include <Stepper.h>
#define STEPS 200
#include <LiquidCrystal.h>

int switchPinA = 3;
int switchPinB = 14; // A0
int switchPinC = 15; // A1
Stepper stepper(STEPS, 7, 5, 6, 4);
LiquidCrystal lcd(8, 9, 10, 11, 12, 13);

void setup(){
  pinMode(switchPinA, INPUT);
  pinMode(switchPinB, OUTPUT);
  pinMode(switchPinC, OUTPUT);
  stepper.setSpeed(10);
  lcd.begin(16, 2);
}

void mtn(int s){
delay(1000);
stepper.step(s);
// lcd.print("test");
}

void loop(){
  int val = digitalRead(switchPinA);
  if(val==LOW)
  {
  mtn(200); // 360 градусов
  }
}

Вот, только тут как видно ничего не работает) - точнее работает, но не так как надо

Не знаю как дальше... Не понимаю как это все дело подружить.

maksim
Offline
Зарегистрирован: 12.02.2012
#include <Stepper.h>
#include <LiquidCrystal.h>

#define STEPS 200
#define button_A 3
#define button_B 14
#define button_C 15

Stepper stepper(STEPS, 7, 5, 6, 4);
LiquidCrystal lcd(8, 9, 10, 11, 12, 13);

int angles[3] = {200, 100, 50};
int angle = 0;

void setup()
{
  stepper.setSpeed(10);
  lcd.begin(16, 2);
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print((angles[angle]*18)/10);
}

void loop()
{
  if(digitalRead(button_B)) 
  {
    angle++;
    if(angle == 3) angle = 0;
    delay(200);
  }

  if(digitalRead(button_C)) 
  {
    angle--;
    if(angle == -1) angle = 2;
    delay(200);
  }

  static int anglePrev;
  if(angle != anglePrev)
  {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print((angles[angle]*18)/10);
    anglePrev = angle;
  }

  if(digitalRead(button_A)) stepper.step(angles[angle]);
}

 

LumbaLumba
Offline
Зарегистрирован: 18.07.2013
lcd.print((angles[angle]*7.2)/10);

Как сделать округление? Сейчас выводится 360.00

Число7.2 взято из-за передаточного числа 2.5

LumbaLumba
Offline
Зарегистрирован: 18.07.2013

Все получилось! Огромное спасибо! (разобрался)

Максим, подскажите, пожалуйста.

Есть 5 аналоговых кнопок подключенных к А0

//ADKeyboard Module
//Developed by DFRobot.com
//Last modified 30/11/2011
//Version 1.0
int adc_key_val[5] ={50, 200, 400, 600, 800 };
int NUM_KEYS = 5;
int adc_key_in;
int key=-1;
int oldkey=-1;
void setup()
{
  pinMode(13, OUTPUT);  //we'll use the debug LED to output a heartbeat
  Serial.begin(9600); // 9600 bps
}
void loop()
{
  adc_key_in = analogRead(0);    // read the value from the sensor 
  digitalWrite(13,LOW); 
  key = get_key(adc_key_in);  // convert into key press
  
  if (key != oldkey)   // if keypress is detected
   {
    delay(50);  // wait for debounce time
    adc_key_in = analogRead(0);    // read the value from the sensor 
    key = get_key(adc_key_in);    // convert into key press
    if (key != oldkey)    
    {   
      oldkey = key;
      if (key >=0){
        digitalWrite(13,HIGH);
        switch(key)
        {
           case 0:Serial.println("S1 OK");   
                  break;
           case 1:Serial.println("S2 OK");   
                  break;
           case 2:Serial.println("S3 OK");   
                  break;
           case 3:Serial.println("S4 OK");   
                  break;      
           case 4:Serial.println("S5 OK");   
                  break;  
        }                
      }
    }
  }
 delay(100);
}
// Convert ADC value to key number
int get_key(unsigned int input)
{
    int k;
    for (k = 0; k < NUM_KEYS; k++)
    {
      if (input < adc_key_val[k])
     {
            return k;
        }
   }
       if (k >= NUM_KEYS)k = -1;  // No valid key pressed
       return k;
}

IR t/r к 2

// 0.1 by pmalmsten http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1176098434
// 0.2 by farkinga
// 0.3 by farkinga - adds cool behaviors
/* 0.4 by pstrobl 
   changed the original program to use on IR Kit For Arduino Model: DFR0107 32 bit controller. 
   All keypresses are sent to the serial monitor at 9600 baud.
   pulseIn is always HIGH. The phototransistor in the kit does not invert the signal.
   uses pin 13 for heartbeat debug
   32 bits requires a long variable, so divided up into two 15 bit so can use integer variables
   use the first 15 bits of the 32 bits for remote and data stream verification. This code is always the same for every button press
   use the last 15 of the 32 bits for button press selection. This code changes for each button.
   ignore the middle 2 bits, it never changes.  
*/
 
#define IR_BIT_LENGTH 32    // number of bits sent by IR remote
#define FirstLastBit 15     // divide 32 bits into two 15 bit chunks for integer variables. Ignore center two bits. they are all the same.
#define BIT_1 1500          // Binary 1 threshold (Microseconds)
#define BIT_0 450           // Binary 0 threshold (Microseconds)
#define BIT_START 4000      // Start bit threshold (Microseconds)
 
#define IR_PIN 2            // IR Sensor pin
#define LED_PIN 13          // LED goes off when signal is received
 
int debug = 0;              // flag as 1 to output raw IR pulse data stream length in microseconds
int output_verify = 0;      // flag as 1 to print decoded verification integers. same number for all buttons
int output_key = 0;         // flag as 1 to print decoded key integers
int remote_verify = 16128;  // verifies first bits are 11111100000000 different remotes may have different start codes
 
void setup() {
  pinMode(LED_PIN, OUTPUT); //This shows when ready to recieve
  pinMode(IR_PIN, INPUT);
  digitalWrite(LED_PIN, LOW);
  Serial.begin(9600);
}
 
void loop() {
  digitalWrite(LED_PIN, HIGH);
  int key = get_ir_key();
   
  digitalWrite(LED_PIN, LOW);  // turn LED off while processing response
  do_response(key);
  delay(130);                  // 2 cycle delay to cancel duplicate keypresses
}
 
/*
  wait for a keypress from the IR remote, and return the
  integer mapping of that key (e.g. power button on remote returns 
  the integer 1429)
*/
 
int get_ir_key() 
{
  int pulse[IR_BIT_LENGTH];
  int bits[IR_BIT_LENGTH];
 
  do {} //Wait for a start bit
  while(pulseIn(IR_PIN, HIGH) < BIT_START);
 
  read_pulse(pulse);
  pulse_to_bits(pulse, bits);
  RemoteVerify(bits);
  return bits_to_int(bits);
}
 
 
/*
  use pulseIn to receive IR pulses from the remote.
  Record the length of these pulses (in ms) in an array
*/
 
void read_pulse(int pulse[])
{
  for (int i = 0; i < IR_BIT_LENGTH; i++)
  {
    pulse[i] = pulseIn(IR_PIN, HIGH);
  }
}
 
/*
  IR pulses encode binary "0" as a short pulse, and binary "1"
  as a long pulse.  Given an array containing pulse lengths,
  convert this to an array containing binary values
*/
 
void pulse_to_bits(int pulse[], int bits[])
{
  if (debug) { Serial.println("-----"); }
  for(int i = 0; i < IR_BIT_LENGTH; i++) 
  {
    if (debug) { Serial.println(pulse[i]); }
    if(pulse[i] > BIT_1) //is it a 1?
    {
      bits[i] = 1;
    }  
    else if(pulse[i] > BIT_0) //is it a 0?
    {
      bits[i] = 0;
    } 
    else //data is invalid...
    {
      Serial.println("Error");
    }
  }
}
 
/*
  check returns proper first 14 check bits
*/
 
void RemoteVerify(int bits[])
{
  int result = 0;
  int seed = 1;
   
  //Convert bits to integer
  for(int i = 0 ; i < (FirstLastBit) ; i++) 
  {       
    if(bits[i] == 1) 
    {
    result += seed;
    }
     
    seed *= 2;
  }
        if (output_verify)
      {
        Serial.print("Remote ");
        Serial.print(result);
        Serial.println(" verification code");
      }
 if (remote_verify != result) {delay (60); get_ir_key();} //verify first group of bits. delay for data stream to end, then try again.
}
 
 
/*
  convert an array of binary values to a single base-10 integer
*/
 
int bits_to_int(int bits[])
{
  int result = 0;
  int seed = 1;
   
  //Convert bits to integer
  for(int i = (IR_BIT_LENGTH-FirstLastBit) ; i < IR_BIT_LENGTH ; i++) 
  {       
    if(bits[i] == 1) 
    {
    result += seed;
    }   
    seed *= 2;
  }
  return result;
}
 
 
/* 
  respond to specific remote-control keys with different behaviors
*/
 
void do_response(int key)
{  
   
  if (output_key)
   {
      Serial.print("Key ");
      Serial.println(key);
   }
   
  switch (key)
  {
    case 32640:  // turns on UUT power
      Serial.println("POWER");
      break;
 
    case 32385:  // FUNC/STOP turns off UUT power
      Serial.println("FUNC/STOP");
      break;
 
    case 32130:  // |<< ReTest failed Test
      Serial.println("|<<");
      break;
 
    case 32002:  // >|| Test
      Serial.println(">||");
      break;
 
    case 31875:  // >>| perform selected test number
      Serial.println(">>|");
      break;
 
    case 32512:  // VOL+ turns on individual test beeper
      Serial.println("VOL+");
      break;
 
    case 31492:  // VOL- turns off individual test beeper
      Serial.println("VOL-");
      break;
 
    case 31620:  // v scroll down tests
      Serial.println("v");
      break;
 
    case 31365:  // ^ scroll up tests
      Serial.println("^");
      break;
 
    case 30982:  // EQ negative tests internal setup
      Serial.println("EQ");
      break;
 
    case 30855:  // ST/REPT Positive tests Select Test and Repeat Test
    Serial.println("ST/REPT");
      break;
 
    case 31110:  // 0
      Serial.println("0");
      break;
 
    case 30600:  // 1
      Serial.println("1");
      break;
 
    case 30472:  // 2
      Serial.println("2");
      break;
 
    case 30345:  // 3
      Serial.println("3");
      break;
 
    case 30090:  // 4
      Serial.println("4");
      break;
 
    case 29962:  // 5
      Serial.println("5");
      break;
 
    case 29835:  // 6
      Serial.println("6");
      break;
 
    case 29580:  // 7
      Serial.println("7");
      break;
 
    case 29452:  // 8
      Serial.println("8");
      break;
 
    case 29325:  // 9
      Serial.println("9");
      break;
      
    default:
      {
        Serial.print("Key ");
        Serial.print(key);
        Serial.println(" not programmed");
      }
    break;
  }
}

Как это дело подружить? Работает по отдельности. Когда пытаюсь их соединить в одно целое аналоговые кнопки не работают - работает только IR

У меня получилось следующее

#define IR_BIT_LENGTH 32    // number of bits sent by IR remote
#define FirstLastBit 15     // divide 32 bits into two 15 bit chunks for integer variables. Ignore center two bits. they are all the same.
#define BIT_1 1500          // Binary 1 threshold (Microseconds)
#define BIT_0 450           // Binary 0 threshold (Microseconds)
#define BIT_START 4000      // Start bit threshold (Microseconds)
 
#define IR_PIN 2            // IR Sensor pin
#define LED_PIN 13          // LED goes off when signal is received

int adc_key_val[5] ={50, 200, 400, 600, 800 };
int NUM_KEYS = 5;
int adc_key_in;
int key=-1;
int oldkey=-1;

void setup()
{
  pinMode(13, OUTPUT);  //we'll use the debug LED to output a heartbeat
  Serial.begin(9600); // 9600 bps
  
  pinMode(LED_PIN, OUTPUT); //This shows when ready to recieve
  pinMode(IR_PIN, INPUT);
  digitalWrite(LED_PIN, LOW);
  
}

void loop()
{
  adc_key_in = analogRead(0);    // read the value from the sensor 
  //digitalWrite(13,LOW); 
  key = get_key(adc_key_in);  // convert into key press
  
  if (key != oldkey)   // if keypress is detected
   {
    delay(50);  // wait for debounce time
    adc_key_in = analogRead(0);    // read the value from the sensor 
    key = get_key(adc_key_in);    // convert into key press
    if (key != oldkey)    
    {   
      oldkey = key;
      if (key >=0){
        //digitalWrite(13,HIGH);
        switch(key)
        {
           case 0:Serial.println("S1 OK");   
                  break;
           case 1:Serial.println("S2 OK");   
                  break;
           case 2:Serial.println("S3 OK");   
                  break;
           case 3:Serial.println("S4 OK");   
                  break;      
           case 4:Serial.println("S5 OK");   
                  break;  
        }                
      }
    }
  }
 delay(100);
}
// Convert ADC value to key number
int get_key(unsigned int input)
{
    int k;
    for (k = 0; k < NUM_KEYS; k++)
    {
      if (input < adc_key_val[k])
     {
            return k;
        }
   }
       if (k >= NUM_KEYS)k = -1;  // No valid key pressed
       return k;
}

int get_ir_key() 
{
  int pulse[IR_BIT_LENGTH];
  int bits[IR_BIT_LENGTH];
 
  do {} //Wait for a start bit
  while(pulseIn(IR_PIN, HIGH) < BIT_START);
 
  read_pulse(pulse);
  pulse_to_bits(pulse, bits);
  RemoteVerify(bits);
  return bits_to_int(bits);
}
 
 
/*
  use pulseIn to receive IR pulses from the remote.
  Record the length of these pulses (in ms) in an array
*/
 
void read_pulse(int pulse[])
{
  for (int i = 0; i < IR_BIT_LENGTH; i++)
  {
    pulse[i] = pulseIn(IR_PIN, HIGH);
  }
}
 
/*
  IR pulses encode binary "0" as a short pulse, and binary "1"
  as a long pulse.  Given an array containing pulse lengths,
  convert this to an array containing binary values
*/
 
void pulse_to_bits(int pulse[], int bits[])
{
  if (debug) { Serial.println("-----"); }
  for(int i = 0; i < IR_BIT_LENGTH; i++) 
  {
    if (debug) { Serial.println(pulse[i]); }
    if(pulse[i] > BIT_1) //is it a 1?
    {
      bits[i] = 1;
    }  
    else if(pulse[i] > BIT_0) //is it a 0?
    {
      bits[i] = 0;
    } 
    else //data is invalid...
    {
      Serial.println("Error");
    }
  }
}
 
/*
  check returns proper first 14 check bits
*/
 
void RemoteVerify(int bits[])
{
  int result = 0;
  int seed = 1;
   
  //Convert bits to integer
  for(int i = 0 ; i < (FirstLastBit) ; i++) 
  {       
    if(bits[i] == 1) 
    {
    result += seed;
    }
     
    seed *= 2;
  }
        if (output_verify)
      {
        Serial.print("Remote ");
        Serial.print(result);
        Serial.println(" verification code");
      }
 if (remote_verify != result) {delay (60); get_ir_key();} //verify first group of bits. delay for data stream to end, then try again.
}
 
 
/*
  convert an array of binary values to a single base-10 integer
*/
 
int bits_to_int(int bits[])
{
  int result = 0;
  int seed = 1;
   
  //Convert bits to integer
  for(int i = (IR_BIT_LENGTH-FirstLastBit) ; i < IR_BIT_LENGTH ; i++) 
  {       
    if(bits[i] == 1) 
    {
    result += seed;
    }   
    seed *= 2;
  }
  return result;
}
 
 
/* 
  respond to specific remote-control keys with different behaviors
*/
 
void do_response(int key)
{  
   
  if (output_key)
   {
      Serial.print("Key ");
      Serial.println(key);
   }
   
  switch (key)
  {
    case 32640:  // turns on UUT power
      Serial.println("POWER");
      break;
 
    case 32385:  // FUNC/STOP turns off UUT power
      Serial.println("FUNC/STOP");
      break;
 
    case 32130:  // |<< ReTest failed Test
      Serial.println("|<<");
      break;
 
    case 32002:  // >|| Test
      Serial.println(">||");
      break;
 
    case 31875:  // >>| perform selected test number
      Serial.println(">>|");
      break;
 
    case 32512:  // VOL+ turns on individual test beeper
      Serial.println("VOL+");
      break;
 
    case 31492:  // VOL- turns off individual test beeper
      Serial.println("VOL-");
      break;
 
    case 31620:  // v scroll down tests
      Serial.println("v");
      break;
 
    case 31365:  // ^ scroll up tests
      Serial.println("^");
      break;
 
    case 30982:  // EQ negative tests internal setup
      Serial.println("EQ");
      break;
 
    case 30855:  // ST/REPT Positive tests Select Test and Repeat Test
    Serial.println("ST/REPT");
      break;
 
    case 31110:  // 0
      Serial.println("0");
      break;
 
    case 30600:  // 1
      Serial.println("1");
      break;
 
    case 30472:  // 2
      Serial.println("2");
      break;
 
    case 30345:  // 3
      Serial.println("3");
      break;
 
    case 30090:  // 4
      Serial.println("4");
      break;
 
    case 29962:  // 5
      Serial.println("5");
      break;
 
    case 29835:  // 6
      Serial.println("6");
      break;
 
    case 29580:  // 7
      Serial.println("7");
      break;
 
    case 29452:  // 8
      Serial.println("8");
      break;
 
    case 29325:  // 9
      Serial.println("9");
      break;
      
    default:
      {
        Serial.print("Key ");
        Serial.print(key);
        Serial.println(" not programmed");
      }
    break;
  }
}

Не погу понять в чем проблема.

maksim
Offline
Зарегистрирован: 12.02.2012

LumbaLumba пишет:

lcd.print((angles[angle]*7.2)/10);

Как сделать округление? Сейчас выводится 360.00

Число7.2 взято из-за передаточного числа 2.5

lcd.print((angles[angle]*72)/100);

 

LumbaLumba
Offline
Зарегистрирован: 18.07.2013

maksim пишет:

LumbaLumba пишет:

lcd.print((angles[angle]*7.2)/10);

Как сделать округление? Сейчас выводится 360.00

Число7.2 взято из-за передаточного числа 2.5

lcd.print((angles[angle]*72)/100);

 

Так я пробовал, но при запуске первое чилсо стало выводится "-295", а при нажатии на В С все было ок.

Откуда оно взялось - так и не понял.

maksim
Offline
Зарегистрирован: 12.02.2012
lcd.print((angles[angle]*72L)/100);

 

LumbaLumba
Offline
Зарегистрирован: 18.07.2013

Спасибо!

А по предыдущему посту не подскажите?

Я так понял что-то с переменной key?

maksim
Offline
Зарегистрирован: 12.02.2012

Потому что строки 

  do {} //Wait for a start bit
  while(pulseIn(IR_PIN, HIGH) < BIT_START);

блокируют всю программу и ожидают сигнала с ИК-приемника.

LumbaLumba
Offline
Зарегистрирован: 18.07.2013

Попробовал их закоментировать - не получилось.

Может быть этот кусок?

void read_pulse(int pulse[])
{
  for (int i = 0; i < IR_BIT_LENGTH; i++)
  {
    pulse[i] = pulseIn(2, HIGH);
  }
}

 

maksim
Offline
Зарегистрирован: 12.02.2012

Закоментировать не получится надо менять логику работы кода на неблокирующую.

LumbaLumba
Offline
Зарегистрирован: 18.07.2013

Понятно, придется тогда отложить данную идею.

Еще хотел спросить у вас по предыдущему коду

#include <Stepper.h>
#include <LiquidCrystal.h>

#define STEPS 200
#define button_A 3
#define button_B 14
#define button_C 15

Stepper stepper(STEPS, 7, 5, 6, 4);
LiquidCrystal lcd(8, 9, 10, 11, 12, 13);

int angles[3] = {200, 100, 50};
int angle = 0;

void setup()
{
  stepper.setSpeed(10);
  lcd.begin(16, 2);
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print((angles[angle]*18)/10);
}

void loop()
{
  if(digitalRead(button_B)) 
  {
    angle++;
    if(angle == 3) angle = 0;
    delay(200);
  }

  if(digitalRead(button_C)) 
  {
    angle--;
    if(angle == -1) angle = 2;
    delay(200);
  }

  static int anglePrev;
  if(angle != anglePrev)
  {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print((angles[angle]*18)/10);
    anglePrev = angle;
  }

  if(digitalRead(button_A)) stepper.step(angles[angle]);
}

Как заставить button_A при повтороном нажатии останавливать шд?