I2C Display och Arduino

Berätta om dina pågående projekt.
Användarvisningsbild
4kTRB
Inlägg: 18404
Blev medlem: 16 augusti 2009, 19:04:48

I2C Display och Arduino

Inlägg av 4kTRB »

Har fått hem 2 styck "GeeekPi 2-pack I2C 1602 LCD-skärmmodul 16 x 2 karaktärer seriell blå bakgrundsbelysning LCD-modul" (översättning a la Amazon)
Så nu är mitt projekt att koppla in en sådan och lära mig diverse finesser.
Till att börja med har jag hittat en wiki-sida för displayen med länkar till headerfiler osv. som behöver inkluderas
i koden. Sedan har jag laddat hem Sloeber till Eclipse (phuuu det var svettigt att få det att fungera).
Så jag kommer här framöver presentera framsteg och bakslag under projektets gång.

https://eclipse.baeyens.it

https://wiki.52pi.com/index.php?title=Z-0234

Bild
Användarvisningsbild
4kTRB
Inlägg: 18404
Blev medlem: 16 augusti 2009, 19:04:48

Re: I2C Display och Arduino

Inlägg av 4kTRB »

Testade displayen med ett enkelt program och det fungerade direkt.
Väldigt snyggt med vit text mot blå bakgrund tycker jag.
Det är den äldre versionen av display jag fick från Amazon så adressen är 0x27.
Freenove säljer samma display och de har en manual med exempelprogram med mera.
https://github.com/Freenove/Freenove_LCD_Module

Nu måste jag lära mig lite mer finesser.

Kod: Markera allt

#include "Arduino.h"
#include <LiquidCrystal_I2C.h>
//The setup function is called once at startup of the sketch
// initialize the library with the numbers of the interface pins
LiquidCrystal_I2C lcd(0x27, 16, 2);
bool i2CAddrTest(uint8_t);
void setup() {
	  if (!i2CAddrTest(0x27)) {
	    lcd = LiquidCrystal_I2C(0x3F, 16, 2);
	  }
  lcd.init();                // initialize the lcd
  lcd.backlight();           // Turn on backlight
  lcd.print("hello, world!");// Print a message to the LCD
}

void loop() {
  // (note: line 1 is the second row, since counting begins with 0):
  lcd.setCursor(0, 1);// set the cursor to column 0, line 1
  // print the number of seconds since reset:
  lcd.print("Counter:");
  lcd.print(millis() / 1000);
}

bool i2CAddrTest(uint8_t addr) {
  Wire.begin();
  Wire.beginTransmission(addr);
  if (Wire.endTransmission() == 0) {
    return true;
  }
  return false;
}
I2C_LCD_000.jpg
Du har inte behörighet att öppna de filer som bifogats till detta inlägg.
Användarvisningsbild
Mickecarlsson
EF Sponsor
Inlägg: 3846
Blev medlem: 15 april 2017, 18:06:15
Ort: Malmö
Kontakt:

Re: I2C Display och Arduino

Inlägg av Mickecarlsson »

Sätt en delay(1000); efter sista raden, som det är nu bombar du i2c-bussen ett par hundra tusen gånger i sekunden, eller hur många cykler den gör i loop innan den kör igen.
Användarvisningsbild
4kTRB
Inlägg: 18404
Blev medlem: 16 augusti 2009, 19:04:48

Re: I2C Display och Arduino

Inlägg av 4kTRB »

Vad segt det är med LCD kontra LED. Känns nästan statiskt om jag uppdaterar text för snabbt.

Ok. Tsestar den här koden. Nu blir det snällare väl?

Kod: Markera allt

#include "Arduino.h"
#include <LiquidCrystal_I2C.h>
//The setup function is called once at startup of the sketch
// initialize the library with the numbers of the interface pins
//LiquidCrystal_I2C lcd(0x27, 16, 2);
unsigned long r;
LiquidCrystal_I2C lcd = LiquidCrystal_I2C(0x27, 16, 2);
void setup() {
  lcd.init();                // initialize the lcd
  lcd.backlight();           // Turn on backlight
  lcd.setCursor(2, 0);		 // kolumn 2 och rad 0
  lcd.print("Hello World!");// Print a message to the LCD
}

void loop() {
	lcd.setCursor(2, 1);// set the cursor to column 0, line 1
  // print the number of seconds since reset:
	lcd.print("Counter:");
	r = millis()/1000;
	lcd.print(r);
	if((r%7) == 0){
		lcd.clear();
		lcd.setCursor(2,1);
		lcd.print("Jabbadoo!");
		lcd.setCursor(12,1);
		lcd.print(r);
		delay(1000);
		lcd.clear();
		lcd.setCursor(2, 0);
		lcd.print("Hello World!");
	}
	delay(100);
}
Användarvisningsbild
Mickecarlsson
EF Sponsor
Inlägg: 3846
Blev medlem: 15 april 2017, 18:06:15
Ort: Malmö
Kontakt:

Re: I2C Display och Arduino

Inlägg av Mickecarlsson »

Ja, LCD är lååååångsamma att uppdatera.
Nja, nu bombar du i2c var 100:e millisekund
Om inte r%7 är noll går du till slutet, väntar 100 ms sen skriver du ut Counter igen, sen räknaren, det gör du 9 gånger, sen är r%7 noll och du skriver ut Jabbadoo, väntar en sekund, sen börjar du bomba igen :D
Nu skriver jag detta på iPaden, så jag kan inte hjälpa dig med lite bättre kod, får se om jag startar PC’n och skickar ett exempel på hur jag gör det.
Användarvisningsbild
Mickecarlsson
EF Sponsor
Inlägg: 3846
Blev medlem: 15 april 2017, 18:06:15
Ort: Malmö
Kontakt:

Re: I2C Display och Arduino

Inlägg av Mickecarlsson »

Denna kod är otestad, men ungefär såhär hade jag skrivit koden.
I loop, är det inte dags att uppdatera LCD'n, loopa, när r%7 blir noll anropas funktionen för uppdatering av LCD'n.

Kod: Markera allt

#include "Arduino.h"
#include <LiquidCrystal_I2C.h>
//The setup function is called once at startup of the sketch
// initialize the library with the numbers of the interface pins
//LiquidCrystal_I2C lcd(0x27, 16, 2);
unsigned long r;
LiquidCrystal_I2C lcd = LiquidCrystal_I2C(0x27, 16, 2);
void setup() {
  lcd.init();		// initialize the lcd
  lcd.backlight();		// Turn on backlight
  lcd.setCursor(2, 0);	// kolumn 2 och rad 0
  lcd.print("Hello World!");// Print a message to the LCD
}

void loop() {
	r = millis()/1000;
	if((r%7) == 0)
		{
			LCDprint(r);
		}
	
}

  // print the number of seconds since reset:
void LCDprint(unsigned long sekunder)
{
		lcd.setCursor(2, 1);	// set the cursor to column 2, line 1
		lcd.print("Counter:");
		lcd.print(sekunder);
		lcd.setCursor(2,0);
		lcd.print("Jabbadoo!");
		lcd.print("Hello World!"); // kan tas bort
}
Användarvisningsbild
4kTRB
Inlägg: 18404
Blev medlem: 16 augusti 2009, 19:04:48

Re: I2C Display och Arduino

Inlägg av 4kTRB »

Ok. Det viktiga är att om man loopar utan delay så läggs det mycket
energi på ingenting om jag förstår det rätt.

Jag tror de som hade exemplet i Freenove:s manual ville göra det enkelt för
att komma igång. Även andra sådana där "lär dig"-sidor loopar utan delay...
https://www.makerguides.com/character-i ... -tutorial/
Användarvisningsbild
Mickecarlsson
EF Sponsor
Inlägg: 3846
Blev medlem: 15 april 2017, 18:06:15
Ort: Malmö
Kontakt:

Re: I2C Display och Arduino

Inlägg av Mickecarlsson »

Använde man delay() stannar exekveringen tills delay-tiden är slut.
Kör man loop med anrop till flera funktioner är det effektivare kodning.
Jag har en Arduino som kollar temperatur och luftfuktighet, mäter strömförbrukning från en elmätare, kollar två dörrar att dom är stängda, kollar om ljuset är tänt etc.
Loopen innehåller bara funktionsanrop, inga variabler eller kod för övrigt.
MiaM
Inlägg: 9990
Blev medlem: 6 maj 2009, 22:19:19

Re: I2C Display och Arduino

Inlägg av MiaM »

Oj vilken märklig produkt!

Visst, det är egentligen en bra produkt. Men det har åtminstone förr tillverkats displayer med inbyggt I2C-interface, faktiskt direkt på glaset. Finns inte sånt längre?
Användarvisningsbild
4kTRB
Inlägg: 18404
Blev medlem: 16 augusti 2009, 19:04:48

Re: I2C Display och Arduino

Inlägg av 4kTRB »

Däremot finns dessa adaptrar att få tag i att ansluta
till en standard LCD. Kan ju hända att man behöver
mer pinnar och då behövs bara 2 till I2C.
Användarvisningsbild
JohnGalt
Inlägg: 1052
Blev medlem: 17 maj 2010, 21:16:39
Ort: Helsingborg (omnejd)

Re: I2C Display och Arduino

Inlägg av JohnGalt »

Väldigt bra produkt, tycker jag. Perfekt om man vill köra äldre displayer, VFD och annat, på ett smidigare sätt.
Kul att det fungerar, bara att leka vidare!
Användarvisningsbild
4kTRB
Inlägg: 18404
Blev medlem: 16 augusti 2009, 19:04:48

Re: I2C Display och Arduino

Inlägg av 4kTRB »

Jo då nu leker jag med att skicka tecken från min laptop till Arduino och displayen..

Dels för att jag ska veta hur det fungerar att styra displayen från ett GUI (java)
och samtidigt få en enklare utvärdering av hur tecknen tolkas av displayen.

Som synes av fotot så stämmer tecknen inte riktigt.

Kod som Arduino kör...

Kod: Markera allt

#include "Arduino.h"
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd = LiquidCrystal_I2C(0x27, 16, 2);
const unsigned long BAUDRATE = 19200;
int inByte;
char data;
int index;
const int WRITE_LCD_ROW_1 = 124;
const int WRITE_LCD_ROW_2 = 125;
const int CLEAR_LCD = 126;
const int WHILE_LOOP_BREAK = 127;

void setup() {
	Serial.begin(BAUDRATE);
    data = "0";
	index = 0;
	inByte = 0;
	lcd.init();                								// initialize the lcd
	lcd.backlight();           								// Turn on backlight

	while (!Serial) {
	    ; 													// wait for serial port to connect. Needed for native USB
	}
}

void loop() {
		if (Serial.available() > 0)
			{
				inByte = Serial.read();
				if(inByte == WRITE_LCD_ROW_1){				// rad 1
					lcd.setCursor(index,0);
					index++;
					while(!Serial.available()){
						;
					}
					data = Serial.read();					// hämta tecken
					lcd.print(data);						// skriv tecken till nästa position, vänster till höger
															// rad 1 till rad 2
				}
				if(inByte == WRITE_LCD_ROW_2){				// rad 2
					lcd.setCursor(index,1);
					index++;
					while(!Serial.available()){
						;
					}
					data = Serial.read();
					lcd.print(data);
				}
				if(inByte == CLEAR_LCD){					// kod 126	rensa LCD
					lcd.clear();
					index = 0;
				}
				if(inByte ==  WHILE_LOOP_BREAK){			// kod 127
					lcd.clear();
					Serial.end();			  			  	// nedkoppling av seriekommunikation/com-port
				}
		}
	inByte = 0;

	if(index >=16 )
		index = 0;
	delay(40);
}
IMG_TestSoftware.jpg
Du har inte behörighet att öppna de filer som bifogats till detta inlägg.
Användarvisningsbild
4kTRB
Inlägg: 18404
Blev medlem: 16 augusti 2009, 19:04:48

Re: I2C Display och Arduino

Inlägg av 4kTRB »

Och här Java-koden, trådstyrt så inte GUI fryser...

Kod: Markera allt

package start;

import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JTextField;
import java.awt.Font;
import java.awt.Color;
import javax.swing.JPanel;
import java.awt.GridLayout;
import javax.swing.SwingConstants;
import serial.AppWinSerial;
import threadController.AppWinThreadController;
import javax.swing.UIManager;


import java.awt.Button;

import javax.swing.event.CaretListener;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.event.CaretEvent;
import java.awt.FlowLayout;
import java.awt.Label;
import java.awt.SystemColor;
import javax.swing.JLabel;

public class AppWinLCD {
	private static final int DEFAULTBAUDRATE = 19200;
	private static AppWinThreadController threadController;
	private static Thread threadControllerThread;
	private static AppWinSerial appwinSerial;
	private JFrame frmIclcdapplication;
	private static JTextField[] textField = new JTextField[32];	
	private Button button_1;
	private Button button_2;
	private Button button_3;
	private Button button_4;	
	private JPanel panel_1;
	private JPanel panel_1_1;
	private JPanel panel_2;
	private JPanel panel_2_1;
	private JTextField textField_1;
	private JTextField textField_2;
	private Label label_1;
	private Label label_2;
	private boolean changeTextFlag;
	private boolean eraseTextFlag;

	private static void setUpSerial() {
		appwinSerial = new AppWinSerial();
		appwinSerial.setBaudRate(AppWinLCD.DEFAULTBAUDRATE);		// default baudrate för kommunikation med Arduino
	}

	public static AppWinSerial getAppWinSerial() {
		return appwinSerial;
	}

	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					AppWinLCD window = new AppWinLCD();
					window.frmIclcdapplication.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Create the application.
	 */
	public AppWinLCD() {
		AppWinLCD.setUpSerial();
		initialize();			
		AppWinLCD.scanLCDJTextField();

	}
	
	// Diverse metoder ====================================================================================================================
	private void setChangeTextFlag(boolean value) {
		changeTextFlag = value;
	}
	private boolean getChangeTextFlag() {
		return changeTextFlag;
	}
	private void setEraseTextFlag(boolean value) {
		eraseTextFlag = value;
	}
	private boolean getEraseTextFlag() {
		return eraseTextFlag;
	}

	private void showNumberOfCharRow_1() {		
		int length = this.textField_1.getText().length();
		if(length < 16)
			this.label_1.setText(String.valueOf(length));
		if((length >= 16) && (length < 17) )
			this.label_1.setText("Max!");
		if(length >= 17)
			this.label_1.setText("Radera!");
	}
	private void showNumberOfCharRow_2() {
		int length = this.textField_2.getText().length();
		System.out.println("this.textField_2.getText().length() " + length);
		if(length < 16)
			this.label_2.setText(String.valueOf(length));
		if((length >= 16) && (length < 17) )
			this.label_2.setText("Max!");
		if(length >= 17)
			this.label_2.setText("Radera!");
	}
	/*
	 * Hanterar editeringen av texten så de 32 blå rutorna  fylls i korrekt
	 */
	private void setJTextFieldCharactersRow_1(int caretPosition, boolean changeTextFlag, boolean eraseTextFlag) {
		if(changeTextFlag == true) {
			
			int length = textField_1.getText().length();
			for(int index = 0;index < 16;index++) {							// rensa 
				textField[index].setText(" ");
			}
			length = textField_1.getText().length();						// hämta in text på nytt
			if(length > 16)
				length = 16;
			
			for(int index = 0;index < length;index++) {
				char value = textField_1.getText().charAt(index);
				String str =String.valueOf(value);
				textField[index].setText(str);
			}			
		}
		
		if(eraseTextFlag == true) {											// raderat tecken 
			int length = textField_1.getText().length();				
			for(int index = 0;index < 16;index++) {							// rensa 
				textField[index].setText(" ");
			}
			length = textField_1.getText().length();						// hämta in text på nytt
			if(length > 16)
				length = 16;
			for(int index = 0;index < length ;index++) {
				char value = textField_1.getText().charAt(index);
				String str =String.valueOf(value);
				textField[index].setText(str);
			}
		}		
	}
	private void setJTextFieldCharactersRow_2(int caretPosition, boolean changeTextFlag, boolean eraseTextFlag) {
		
		if(changeTextFlag == true) {
			
			int length = textField_2.getText().length();
			for(int index = 16;index < 32;index++) {							// rensa 
				textField[index].setText(" ");
			}
			length = textField_2.getText().length();						// hämta in text på nytt
			if(length > 16)
				length = 16;
			
			for(int index = 0;index < length;index++) {
				char value = textField_2.getText().charAt(index);
				String str =String.valueOf(value);
				textField[index+16].setText(str);
			}			
		}
		
		if(eraseTextFlag == true) {											// raderat tecken 
			int length = textField_2.getText().length();				
			for(int index = 16;index < 32;index++) {							// rensa 
				textField[index].setText(" ");
			}
			length = textField_2.getText().length();						// hämta in text på nytt
			if(length > 16)
				length = 16;
			for(int index = 0;index < length ;index++) {
				char value = textField_2.getText().charAt(index);
				String str =String.valueOf(value);
				textField[index+16].setText(str);
			}
		}		
	}
	public static void scanLCDJTextField() {	
		char sign = 0;
		for(int index = 0; index <= 31; index++) {
			if(textField[index].getText().isEmpty())
				textField[index].setText(" ");			
			sign = textField[index].getText().charAt(0);
			appwinSerial.loadLcdText((byte) sign, index);
			System.out.print((char)sign + ", ");
		}	
		System.out.println();
	}

	/**
	 * Initialize the contents of the frame.
	 */
	private void initialize() {
		frmIclcdapplication = new JFrame();
		frmIclcdapplication.getContentPane().setBackground(new Color(253, 245, 230));
		frmIclcdapplication.setTitle("I2C_LCD_Application");
		frmIclcdapplication.setBounds(100, 100, 663, 468);
		frmIclcdapplication.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frmIclcdapplication.getContentPane().setLayout(null);


		panel_1 = new JPanel();
		panel_1.setForeground(new Color(0, 0, 0));
		panel_1.setBorder(null);
		panel_1.setBackground(new Color(0, 66, 164));
		panel_1.setBounds(60, 96, 520, 45);
		frmIclcdapplication.getContentPane().add(panel_1);
		panel_1.setLayout(new GridLayout(1, 0, 0, 0));

		panel_2 = new JPanel();
		panel_2 = new JPanel();
		panel_2.setBackground(new Color(0, 66, 164));
		panel_2.setBounds(60, 147, 520, 45);
		frmIclcdapplication.getContentPane().add(panel_2);
		panel_2.setLayout(new GridLayout(1, 0, 0, 0));


		//========================================================================== 1:a raden med 16 blå textFields	
		for(int index=0;index<=15;index++) {
			textField[index] = new JTextField(1);
			textField[index].setHorizontalAlignment(SwingConstants.CENTER);			
			textField[index].setBackground(new Color(0, 82, 164));
			textField[index].setForeground(new Color(255, 255, 255));
			textField[index].setFont(new Font("Tahoma", Font.PLAIN, 30));
			textField[index].setColumns(1);
			textField[index].setText(" ");
			textField[index].setEditable(false);
			panel_1.add(textField[index]);
		}
		//========================================================================== 2:a raden med 16 blå textFields	
		for(int index=16;index<=31;index++) {
			textField[index] = new JTextField(1);
			textField[index].setHorizontalAlignment(SwingConstants.CENTER);			
			textField[index].setBackground(new Color(0, 82, 164));
			textField[index].setForeground(new Color(255, 255, 255));
			textField[index].setFont(new Font("Tahoma", Font.PLAIN, 30));
			textField[index].setColumns(1);
			textField[index].setText(" ");
			textField[index].setEditable(false);
			panel_2.add(textField[index]);
		}

		//========================================================================== START-knapp
		button_1 = new Button("START");		
		button_1.setForeground(new Color(127, 255, 0));
		button_1.setBackground(new Color(46, 139, 87));
		button_1.addMouseListener(new java.awt.event.MouseAdapter() {
			@Override
			public void mouseClicked(java.awt.event.MouseEvent e) {
				if(threadController == null) {					
					threadController = new AppWinThreadController();			// skapa en trådkontroller					
					threadControllerThread = new Thread(threadController);		// låt trådkontrollern bli en tråd					
					try {
						threadControllerThread.start();							// starta upp Seriekommunikationen
					}
					catch(IllegalThreadStateException itse) {
						System.out.println("IllegalThreadStateException");
					}										
				}								
			}
		});
		button_1.setFont(new Font("Monospaced", Font.BOLD, 28));
		button_1.setBounds(524, 326, 113, 45);
		frmIclcdapplication.getContentPane().add(button_1);

		//========================================================================== SEND-knapp
		button_4 = new Button("SEND TEXT TO LCD");
		button_4.setBackground(new Color(255, 250, 205));
		button_4.addMouseListener(new java.awt.event.MouseAdapter() {
			@Override
			public void mouseClicked(java.awt.event.MouseEvent e) {
				if(threadController != null) {
					appwinSerial.setSend_Row_1_Flag(true);						// utför avbrott för att sända data till rad 1 och sedan rad 2
					appwinSerial.setSend_Row_2_Flag(true);
					try {											
						threadControllerThread.interrupt();						// trådavbrott för att utföra kommando		
					}
					catch(SecurityException se) {
						se.printStackTrace();
					}				
				}
			}
		});	
		button_4.setFont(new Font("Monospaced", Font.PLAIN, 28));
		button_4.setBounds(10, 326, 302, 45);
		frmIclcdapplication.getContentPane().add(button_4);

		//========================================================================== CLEAR LCD-knapp
		button_3 = new Button("CLEAR LCD");
		button_3.setBackground(new Color(255, 250, 205));
		button_3.addMouseListener(new java.awt.event.MouseAdapter() {
			@Override
			public void mouseClicked(java.awt.event.MouseEvent e) {
				if(threadController != null) {					
					appwinSerial.setClearLCDFlag(true);							// flagga att ett CLEAR-kommando ska utföras
					try {
						threadControllerThread.interrupt();						// trådavbrott för att utföra kommando
					}
					catch(SecurityException se) {
						se.printStackTrace();
					}
				}	
			}
		});
		button_3.setFont(new Font("Monospaced", Font.PLAIN, 28));
		button_3.setBounds(10, 377, 183, 45);
		frmIclcdapplication.getContentPane().add(button_3);

		//========================================================================== EXIT-knapp
		button_2 = new Button("EXIT");
		button_2.setForeground(new Color(127, 255, 0));
		button_2.setBackground(new Color(46, 139, 87));
		button_2.addMouseListener(new java.awt.event.MouseAdapter() {
			@Override
			public void mouseClicked(java.awt.event.MouseEvent e) {	
				if (threadControllerThread != null) {
					appwinSerial.setStopSignal();								// flagga att kommunikationen med Arduino ska avslutas
					try {
						threadControllerThread.interrupt();						// avsluta Seriekommunikationen
					}
					catch(SecurityException se) {
						se.printStackTrace();
					}
				}
				System.exit(0);
			}			
		});
		button_2.setFont(new Font("Monospaced", Font.BOLD, 28));
		button_2.setBounds(524, 377, 113, 45);
		frmIclcdapplication.getContentPane().add(button_2);

		panel_1_1 = new JPanel();
		panel_1_1.setBackground(new Color(250, 240, 230));
		FlowLayout flowLayout = (FlowLayout) panel_1_1.getLayout();
		flowLayout.setAlignment(FlowLayout.RIGHT);
		panel_1_1.setBounds(10, 203, 627, 53);
		frmIclcdapplication.getContentPane().add(panel_1_1);
		
		
		panel_2_1 = new JPanel();
		panel_2_1.setBackground(new Color(250, 240, 230));
		FlowLayout flowLayout_1 = (FlowLayout) panel_2_1.getLayout();
		flowLayout_1.setAlignment(FlowLayout.RIGHT);
		panel_2_1.setBounds(10, 267, 627, 53);
		frmIclcdapplication.getContentPane().add(panel_2_1);
		
		
		/*
		 * Textfält att skriva in första raden
		 */
		textField_1 = new JTextField();
		textField_1.getDocument().addDocumentListener(new DocumentListener() {

			@Override
			public void insertUpdate(DocumentEvent e) {
				System.out.println("Ändra");
				setChangeTextFlag(true);
			}
 
			@Override
			public void removeUpdate(DocumentEvent e) {
				System.out.println("Radera");
				setEraseTextFlag(true);
			}

			@Override
			public void changedUpdate(DocumentEvent e) {
				System.out.println("Övrigt");
			}
		});

		textField_1.addCaretListener(new CaretListener() {
			public void caretUpdate(CaretEvent e) {	
				
				System.out.println("changeTextFlag = " + getChangeTextFlag());
				System.out.println("eraseTextFlag = " + getEraseTextFlag());				
				int caretPosition = textField_1.getCaretPosition();
				System.out.println("caretUpdate_1 caretPosition = " + caretPosition);
				showNumberOfCharRow_1();												// uppdatera JLabel 
				setJTextFieldCharactersRow_1(caretPosition, changeTextFlag, eraseTextFlag);
				setChangeTextFlag(false);
				setEraseTextFlag(false);
			}
		});
		textField_1.setFont(new Font("Tahloma", Font.PLAIN, 30));
		textField_1.setColumns(16);
		panel_1_1.add(textField_1);
		
		label_1 = new Label("R\u00E4knare");
		label_1.setFont(new Font("Times New Roman", Font.PLAIN, 25));
		label_1.setAlignment(Label.CENTER);
		panel_1_1.add(label_1);


		/*
		 * Textfält att skriva in andra raden
		 */
		textField_2 = new JTextField();
		textField_2.getDocument().addDocumentListener(new DocumentListener() {

			@Override
			public void insertUpdate(DocumentEvent e) {
				System.out.println("Ändra");
				setChangeTextFlag(true);
			}
 
			@Override
			public void removeUpdate(DocumentEvent e) {
				System.out.println("Radera");
				setEraseTextFlag(true);
			}

			@Override
			public void changedUpdate(DocumentEvent e) {
				System.out.println("Övrigt");
			}
		});
		textField_2.addCaretListener(new CaretListener() {
			public void caretUpdate(CaretEvent e) {	
				
				System.out.println("changeTextFlag = " + getChangeTextFlag());
				System.out.println("eraseTextFlag = " + getEraseTextFlag());				
				int caretPosition = textField_2.getCaretPosition();
				System.out.println("caretUpdate_2 caretPosition = " + caretPosition);
				showNumberOfCharRow_2();												// uppdatera JLabel 
				setJTextFieldCharactersRow_2(caretPosition, changeTextFlag, eraseTextFlag);
				setChangeTextFlag(false);
				setEraseTextFlag(false);
			}
		});
		textField_2.setFont(new Font("Tahoma", Font.PLAIN, 30));
		textField_2.setColumns(16);		
		panel_2_1.add(textField_2);

		label_2 = new Label("R\u00E4knare");
		label_2.setFont(new Font("Times New Roman", Font.PLAIN, 25));
		label_2.setAlignment(Label.CENTER);
		panel_2_1.add(label_2);
		
		JPanel panel = new JPanel();
		panel.setForeground(new Color(0, 0, 0));
		panel.setBackground(new Color(253, 245, 230));
		panel.setBounds(60, 18, 520, 38);
		frmIclcdapplication.getContentPane().add(panel);
		
		JLabel lblNewLabel = new JLabel("I2C LCD Test Software");
		panel.add(lblNewLabel);
		lblNewLabel.setForeground(new Color(0, 0, 139));
		lblNewLabel.setBackground(new Color(0, 0, 0));
		lblNewLabel.setFont(new Font("Ink Free", Font.BOLD | Font.ITALIC, 25));
		lblNewLabel.setHorizontalAlignment(SwingConstants.CENTER);
		
		JPanel panel_3 = new JPanel();
		panel_3.setForeground(Color.BLACK);
		panel_3.setBackground(new Color(165, 42, 42));
		panel_3.setBounds(60, 58, 520, 4);
		frmIclcdapplication.getContentPane().add(panel_3);
		
		JPanel panel_3_1 = new JPanel();
		panel_3_1.setForeground(Color.BLACK);
		panel_3_1.setBackground(new Color(165, 42, 42));
		panel_3_1.setBounds(60, 11, 520, 4);
		frmIclcdapplication.getContentPane().add(panel_3_1);

	}																			// end initialize()
}

Kod: Markera allt

package serial;

import java.io.DataOutputStream;
import java.io.IOException;
import com.fazecast.jSerialComm.SerialPort;
import start.AppWinLCD;

public class AppWinSerial implements Runnable {
	private int baudRate;								// serieportens i GUI valda överföringshastighet
	private SerialPort serialPort = null; 				
	private DataOutputStream javaToArduinoOut = null;
	private boolean stopSignal;	
	private boolean clearLCDFlag;
	private boolean send_Row_1_Flag;
	private boolean send_Row_2_Flag;
	private boolean loopFlag;

	private static final byte SEND_ROW_1_DATA_COMMAND = 124;
	private static final byte SEND_ROW_2_DATA_COMMAND = 125;
	private static final byte CLEAR_LCD_COMMAND = 126;
	private static final byte EXIT_ARDUINO_COMMAND = 127;
	
	private byte[] characterArray; 
	
	private byte tecken;


	/*
	 * Konstruktor till objekt av typen AppWinSerial
	 */
	public AppWinSerial() {
		this.stopSignal = false;
		this.send_Row_1_Flag = false;
		this.send_Row_2_Flag = false;
		this.clearLCDFlag = false;
		this.loopFlag = true;
		this.characterArray = new byte[32];
	}

	/*
	 *  Denna metod anropas vid tryck på knappen START i GUI
	 */
	public void run() {
		try {
			startSerial();
		} catch (InterruptedException e) {
			System.out.println("InterruptedException in Serial run()");
		}
	}

	/*
	 * Påbörjar en kontakt med den COM-port som Arduino är ansluten till och
	 * Denna metod anropas vid tryck på knappen START i GUI.
	 */

	private void startSerial() throws InterruptedException {
		boolean flag = this.comPortSetUp();				// konfigurerar porten
		if(flag) {
			this.LCDcontroller();
		}			
	}
	/*
	 * Baudrate Default är 9600bps
	 * Metoden sätter värdet
	 */
	public void setBaudRate(int baudrate) {
		baudRate = baudrate;
	}
	/*
	 * Returnerar aktuellt satt baudrate
	 */
	public int getBaudRate() {
		return baudRate;
	}
	/*
	 * Flagga att ett tecken ska skickas till Arduino
	 * för att visas i LCD-display rad 1
	 */
	public void setSend_Row_1_Flag(boolean value) {
		this.send_Row_1_Flag = value;
	}	
	public boolean getSend_Row_1_Flag() {
		return this.send_Row_1_Flag;
	}
	/*
	 * Flagga att ett tecken ska skickas till Arduino
	 * för att visas i LCD-display rad 2
	 */
	public void setSend_Row_2_Flag(boolean value) {
		this.send_Row_2_Flag = value;
	}	
	public boolean getSend_Row_2_Flag() {
		return this.send_Row_2_Flag;
	}
	/*
	 * Om denna flagga sätts true raderas innehållet
	 * på LCD-displayen
	 */
	public void setClearLCDFlag(boolean value) {
		this.clearLCDFlag = value;
	}
	public boolean getClearLCDFlag() {
		return clearLCDFlag;
	}
	/*
	 * Om denna flagga sätts true så indikeras att
	 * kommunikationen med Arduino ska avslutas
	 */
	public void setStopSignal() {
		this.stopSignal = true;
	}

	public boolean getStopSignal() {
		return this.stopSignal;
	}

	/*
	 * Här lagras de tecken som ska skrivas till LCD-displayen
	 * Tecknen som knappats in i GUI skickas hit vid tryck på
	 * knappen SEND i GUI.
	 */
	public void loadLcdText(byte character, int index) {
		if(index <= 31)
			characterArray[index] = character;	
	}
	/*
	 * Här hämtas de tecken som ska skrivas till LCD-displayen
	 * LCDcontroller() skickar tecken för tecken till
	 * Arduino då ett SEND-avbrott sker i while-loopen som
	 * motsvarar ett SEND-kommando.
	 */
	private byte getLcdText(int index) {
		return this.characterArray[index];
	}

	public void setLoopFlag(boolean value) {
		this.loopFlag = value;
	}

	public boolean getLoopFlag() {
		return this.loopFlag;
	}



	/*
	 * Metod. Scannar av vilka COM-portar som finns tillgängliga och om Arduino är ansluten
	 * till någon av dessa. Port med Arduino öppnas och porten konfigureras.
	 */
	public boolean comPortSetUp() throws InterruptedException {
		boolean ArduinoUnoFlag = false;
		int ArduinoUnoIndex = -1;	
		SerialPort[] sp = SerialPort.getCommPorts();		
		System.out.println("Antal tillgängliga seriella portar: "+sp.length);				
		for(int j=0;j<sp.length;j++) {
			System.out.println(sp[j].getDescriptivePortName()+" öppen = "+sp[j].isOpen());
			if(sp[j].getDescriptivePortName().contains("Arduino Uno")){
				ArduinoUnoFlag = true;
				ArduinoUnoIndex = j;
			}
		}
		if(ArduinoUnoFlag) {
			serialPort = sp[ArduinoUnoIndex];	
			if(serialPort.isOpen()) {
				serialPort.closePort(); 							// Close connection
			}
			if(!serialPort.isOpen()) {
				serialPort.openPort(); 								// Open connection
			}			
			Thread.sleep(500);
			serialPort.clearDTR();									// Arduino Reset			
			serialPort.setBaudRate(this.getBaudRate());
			serialPort.setComPortTimeouts(SerialPort.TIMEOUT_READ_SEMI_BLOCKING, 2500, 0);

			System.out.println(serialPort.getDescriptivePortName()+ " öppnad = "+serialPort.isOpen());			
		}		
		return ArduinoUnoFlag;
	}

	/*
	 * while-loop som utför saker då en flagga är satt till true.
	 * Knapparna i GUI sätter flaggorna. Loopen avbryts då flaggan stopSignal är true
	 */
	public void LCDcontroller() {
		System.out.println("LCDcontroller");
		try
		{	
			javaToArduinoOut = new DataOutputStream(serialPort.getOutputStream());				
		}
		catch(IllegalStateException  e)
		{
			e.printStackTrace();
		}

		while(true)																						// loopa runt och detektera satta flaggor för olika uppgifter
		{
			if(Thread.interrupted()) {						
				if(this.getSend_Row_1_Flag()) {	
					AppWinLCD.scanLCDJTextField();
					for(int index=0; index<=15; index++) {
						tecken = this.getLcdText(index);
						System.out.print((char)tecken + " / ");												
					}
					System.out.println();
					
					for(int index=0;index<=15;index++) {
						try {					
							javaToArduinoOut.writeByte(AppWinSerial.SEND_ROW_1_DATA_COMMAND);			// välj menyval för att ta emot ett tecken													
						}													  
						catch(IOException e1) {	
							e1.printStackTrace();
						}											
						try {					
							javaToArduinoOut.writeByte(this.getLcdText(index));															
						}													  
						catch(IOException e2) {	
							e2.printStackTrace();
						} 
					}
					this.setSend_Row_1_Flag(false);			
				}
				
				if(this.getSend_Row_2_Flag()) {															// sänd tecken att visas i rad 2											
					System.out.println("this.getSendFlag() " + this.getSend_Row_2_Flag());
					for(int index = 16; index<=31; index++) {
						try {					
							javaToArduinoOut.writeByte(AppWinSerial.SEND_ROW_2_DATA_COMMAND);			// välj menyval för att ta emot ett tecken													
						}													  
						catch(IOException e1) {	
							e1.printStackTrace();
						}											
						try {					
							javaToArduinoOut.writeByte(this.getLcdText(index));															
						}													  
						catch(IOException e2) {	
							e2.printStackTrace();
						}
						System.out.print( (char)this.getLcdText(index) + ", ");
					}

					this.setSend_Row_2_Flag(false);				
				}

				if(this.getClearLCDFlag()) {												
					System.out.println("this.getClearLCDFlag() " + this.getClearLCDFlag());

					try {					
						javaToArduinoOut.writeByte(AppWinSerial.CLEAR_LCD_COMMAND);			// skicka kommando för clear av LCD-display										
					}			
					catch(IOException e1) {	
						e1.printStackTrace();
					}
					this.setClearLCDFlag(false);
					System.out.println("126");
				}
				if(this.getStopSignal()) {
					System.out.println("this.getStopSignal() " + this.getStopSignal());	
					try {
						javaToArduinoOut.writeByte(AppWinSerial.EXIT_ARDUINO_COMMAND);		// skicka tecken till Arduino för att avsluta seriekommunikation																// för att avsluta, hoppa ur while-loop
					}													  
					catch(IOException e1) {	
						e1.printStackTrace();
					}
					System.out.println("127");	
					break;																	// avbryt while-loop
				}
			}
		}																					// end while			
		if(serialPort.isOpen()) {
			System.out.println("serialPort.isOpen()");
			serialPort.closePort();								// koppla ned com-porten
		}
		try {
			javaToArduinoOut.flush();
		} catch (IOException e) {
			e.printStackTrace();
		}
		try {
			System.out.println("javaToArduinoOut.close");
			javaToArduinoOut.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		System.out.println("System.exit(0)");
	}

}

Kod: Markera allt

package threadController;
import serial.AppWinSerial;
import start.AppWinLCD;

public class AppWinThreadController implements Runnable {
	private Thread	arduinoSerialThread;
	private static final int   TIMER_INTERVAL = 500;
	private AppWinSerial appwinSerial;
	public AppWinThreadController() {
		
	}
	public void run() {
		appwinSerial = AppWinLCD.getAppWinSerial();
		arduinoSerialThread = new Thread(appwinSerial);		// låt appwinSerial bli en tråd
		Thread.currentThread().setName("ControllerThread");
		arduinoSerialThread.start();							
		while(true) {
			try {
				Thread.sleep(TIMER_INTERVAL);
			}
			catch(InterruptedException ie) {				
				arduinoSerialThread.interrupt();
			}
			if(Thread.interrupted() && appwinSerial.getStopSignal()) {
				arduinoSerialThread.interrupt();
				break;
			}
		}
	}
}
Användarvisningsbild
4kTRB
Inlägg: 18404
Blev medlem: 16 augusti 2009, 19:04:48

Re: I2C Display och Arduino

Inlägg av 4kTRB »

HIttade en beskrivning på hur det går att programmera en fristående ATmega328P utan att ens behöva kristall då den
är satt att operera på 1MHz internt. https://www.brennantymrak.com/articles/ ... th-arduino
Det här kan vara rätt så trevligt för mitt projekt som bara ska mäta en pulstid och sedan presentera på en LCD.
Att installera en UNO för så lite känns onödigt kostsamt.
Wihelm
Inlägg: 600
Blev medlem: 18 juni 2019, 17:30:19
Ort: Nybro

Re: I2C Display och Arduino

Inlägg av Wihelm »

Den går i 8MHz utan kristall om man ändra CKDIV8 fuse.
Screenshot 2023-07-12 153803.png
Du har inte behörighet att öppna de filer som bifogats till detta inlägg.
Skriv svar