Skocz do zawartości

Bardzo prosta implementacja SPI master na zestawie FPGA "Elbertv.2"


FlyingDutch

Pomocna odpowiedź

Cześć,

jestem w trakcie prac nad zbieraniem sampli sygnału audio na zestawie FPGA "Sipeed Tang Nano 4K" i potrzebuje w celu debugowania układu jakiegoś kanału do komunikacji z portem szeregowym, lub Arduino. Chciałem użyć któregoś z IP Cores z "Gowin EDA" ale zarówno UART jak i "SPI Master" są tak przekombinowane, że ich użycie wymaga napisania sporej ilości kodu. Postanowiłem więc użyć zestawu FPGA "Elbert v.2" w celu napisania prostego kodu do komunikacji za pomocą protokołu SPI . Powstał więc bardzo prosty "SPI Master", który jest uruchomiony na zestawie FPGA i połączony za pomocą protokołu SPI z "Arduino UNO", które odbiera dane i wyświetla je za pomocą "Monitora portu szeregowego". Do samego kodu "SPI Master'a" został dołączony "debouncer"  do przycisku i generator pojedynczego impulsu (o długości okresu zegara), który inicjuje wysłanie jednego bajtu danych. W celu wygenerowania jednego bardzo krótkiego impulsu napisałem (za pomocą kilku przerzutników typu D) i bramki AND układ generatora monostabilnego. Tutaj wynik symulacji działania generatora monostabilnego:

Monostable_ff_sim_.thumb.png.88badce43bd183ae3112b29509d6a71a.png

Układ działa w ten sposób, że naciśnięcie przycisku (SW1 z Elbert'a) powoduje wysłanie jednego bajtu danych do Arduino za pomocą SPI. Tak wygląda układ testowy (potrzebny był poza FPGA i Arduino 4-liniowy konwerter poziomów logicznych):

IMG_20220330_132907_1CS.thumb.jpg.6e72523d2d7b5af85608526675ec3e9d.jpg

Tutaj kod w VHDL głównego modułu (a właściwie entity) projektu - plik "lw_spi_master.vhd ":

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;

-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity lw_spi_master is
generic (
	c_clkfreq 			: integer := 12_000_000;
	c_sclkfreq 			: integer := 5_000_000;
	c_cpol				: std_logic := '0';
	c_cpha				: std_logic := '0'
);
Port ( 
	clk_i 			: in  STD_LOGIC;
	en_i_Low 		: in  STD_LOGIC;
	mosi_data_i 	: in  STD_LOGIC_VECTOR (7 downto 0);
	miso_data_o 	: out STD_LOGIC_VECTOR (7 downto 0);
	data_ready_o 	: out STD_LOGIC;
	cs_o 			   : out STD_LOGIC;
	sclk_o 			: out STD_LOGIC;
	mosi_o 			: out STD_LOGIC;
	miso_i 			: in  STD_LOGIC
);
end lw_spi_master;

architecture Behavioral of lw_spi_master is

  component debounce is
       port (  clk    : IN  STD_LOGIC;  --input clock
					button  : IN  STD_LOGIC;  --input signal to be debounced
					result  : OUT STD_LOGIC); --debounced signal
  end component;	
  
  component monostable_ff is
     port(
           mono_pulse : out std_logic;		
           clk : in std_logic;  
           reset: in std_logic;  
           key :in  std_logic    
         );
  end component;

signal write_reg	: std_logic_vector (7 downto 0) 	:= (others => '0');	
signal read_reg		: std_logic_vector (7 downto 0) 	:= (others => '0');	

signal en_i		   : std_logic := '0';
signal sclk_en		: std_logic := '0';
signal sclk			: std_logic := '0';
signal sclk_prev	: std_logic := '0';
signal sclk_rise	: std_logic := '0';
signal sclk_fall	: std_logic := '0';

signal pol_phase	: std_logic_vector (1 downto 0) := (others => '0');
signal mosi_en		: std_logic := '0';
signal miso_en		: std_logic := '0';

signal en_i_DB		: std_logic;
signal cnt : std_logic_vector (10 downto 0) 	:= (others => '0');	

constant c_edgecntrlimdiv2	: integer := c_clkfreq/(c_sclkfreq*2);
signal edgecntr			: integer range 0 to c_edgecntrlimdiv2 := 0;

signal cntr 	: integer range 0 to 15 := 0;
signal small_cnt 	: integer range 0 to 1000 := 0;
signal blokada 	: integer range 0 to 3 := 0;

type states is (S_IDLE, S_TRANSFER);
signal state : states := S_IDLE;

--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
begin

C1: debounce port map (clk_i,en_i_Low, en_i_DB);

C2: monostable_ff port map (
                             mono_pulse => en_i,	
                             clk  => clk_i,
                             reset => '1',  
                             key  => not en_i_DB   
                           );

--en_i <= not(en_i_DB);

pol_phase <= c_cpol & c_cpha;

P_SAMPLE_EN : process (pol_phase, sclk_fall, sclk_rise) begin

	case pol_phase is
	
		when "00" =>
			
			mosi_en <= sclk_fall;
			miso_en	<= sclk_rise;
			
		when "01" =>
			
			mosi_en <= sclk_rise;
			miso_en	<= sclk_fall;		

		when "10" =>
			
			mosi_en <= sclk_rise;
			miso_en	<= sclk_fall;			

		when "11" =>

			mosi_en <= sclk_fall;
			miso_en	<= sclk_rise;	

		when others =>
	
	end case;

end process;

P_RISEFALL_DETECT : process (sclk, sclk_prev) begin

	if (sclk = '1' and sclk_prev = '0') then
		sclk_rise <= '1';
	else
		sclk_rise <= '0';
	end if;
	
	if (sclk = '0' and sclk_prev = '1') then
		sclk_fall <= '1';
	else
		sclk_fall <= '0';
	end if;	

end process;


P_MAIN : process (clk_i) begin
if (rising_edge(clk_i)) then

	sclk_prev	<= sclk;
	
	case state is
	
		when S_IDLE =>	
		
			cs_o			<= '1';
			mosi_o			<= '0';
			data_ready_o	<= '0';			
			sclk_en			<= '0';
			cntr			<= 0; 
			
			if (c_cpol = '0') then
				sclk_o	<= '0';
			else
				sclk_o	<= '1';
			end if;	
		
			if (en_i = '1') then
				state		<= S_TRANSFER;
				sclk_en		<= '1';
				write_reg	<= mosi_data_i;
				mosi_o		<= mosi_data_i(7);
				read_reg	<= x"00";
			end if;
		
		when S_TRANSFER =>		
		
			cs_o	<= '0';
			mosi_o	<= write_reg(7);

		
			if (c_cpha = '1') then	
			
				if (cntr = 0) then
					sclk_o	<= sclk;
					if (miso_en = '1') then
						read_reg(0)				<= miso_i;
						read_reg(7 downto 1) 	<= read_reg(6 downto 0);
						cntr					<= cntr + 1;
					end if;				
				elsif (cntr = 8) then
					data_ready_o	<= '1';
					miso_data_o		<= read_reg;
					if (mosi_en = '1') then
						data_ready_o	<= '0';
						if (en_i = '1') then
							write_reg	<= mosi_data_i;
							mosi_o		<= mosi_data_i(7);	
							sclk_o		<= sclk;							
							cntr		<= 0;
						else
							state	<= S_IDLE;
							cs_o	<= '1';								
						end if;	
					end if;
				elsif (cntr = 9) then
					if (miso_en = '1') then
						state	<= S_IDLE;
						cs_o	<= '1';
					end if;						
				else
					sclk_o	<= sclk;
					if (miso_en = '1') then
						read_reg(0)				<= miso_i;
						read_reg(7 downto 1) 	<= read_reg(6 downto 0);
						cntr					<= cntr + 1;
					end if;
					if (mosi_en = '1') then
						mosi_o	<= write_reg(7);
						write_reg(7 downto 1) 	<= write_reg(6 downto 0);
					end if;
				end if;
				
			else	-- c_cpha = '0'
			
				if (cntr = 0) then
					sclk_o	<= sclk;					
					if (miso_en = '1') then
						read_reg(0)				<= miso_i;
						read_reg(7 downto 1) 	<= read_reg(6 downto 0);
						cntr					<= cntr + 1;
					end if;
				elsif (cntr = 8) then
				
					data_ready_o	<= '1';
					miso_data_o		<= read_reg;
					sclk_o			<= sclk;
					if (mosi_en = '1') then
						data_ready_o	<= '0';
						if (en_i = '1') then
							write_reg	<= mosi_data_i;
							mosi_o		<= mosi_data_i(7);		
							cntr		<= 0;
						else
							cntr	<= cntr + 1;
						end if;	
						if (miso_en = '1') then
							state	<= S_IDLE;
							cs_o	<= '1';							
						end if;
					end if;		
				elsif (cntr = 9) then
					if (miso_en = '1') then
						state	<= S_IDLE;
						cs_o	<= '1';
					end if;
				else
					sclk_o	<= sclk;
					if (miso_en = '1') then
						read_reg(0)				<= miso_i;
						read_reg(7 downto 1) 	<= read_reg(6 downto 0);
						cntr					<= cntr + 1;
					end if;
					if (mosi_en = '1') then
						write_reg(7 downto 1) 	<= write_reg(6 downto 0);
					end if;
				end if;			
				
			end if;
		
	end case;
	
end if;
end process;

P_SCLK_GEN : process (clk_i) begin
if (rising_edge(clk_i)) then

	if (sclk_en = '1') then
		if edgecntr = c_edgecntrlimdiv2-1 then
			sclk 		<= not sclk;
			edgecntr	<= 0;
		else
			edgecntr	<= edgecntr + 1;
		end if;	
	else
		edgecntr	<= 0;
		if (c_cpol = '0') then
			sclk	<= '0';
		else
			sclk	<= '1';
		end if;
	end if;

end if;
end process;

end Behavioral;

W tym pliku jest zawarta cała implementacja "SPI Master'a". Widać też użycia komponentów "debouncer'a" i generatora monostabilnego. Tutaj kod "deuboncer'a":

LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_unsigned.all;

ENTITY debounce IS
  GENERIC(
    counter_size  :  INTEGER := 20); --counter size (19 bits gives 10.5ms with 50MHz clock)
  PORT(
    clk     : IN  STD_LOGIC;  --input clock
    button  : IN  STD_LOGIC;  --input signal to be debounced
    result  : OUT STD_LOGIC); --debounced signal
END debounce;

ARCHITECTURE logic OF debounce IS
  SIGNAL flipflops   : STD_LOGIC_VECTOR(1 DOWNTO 0); --input flip flops
  SIGNAL counter_set : STD_LOGIC;                    --sync reset to zero
  SIGNAL counter_out : STD_LOGIC_VECTOR(counter_size DOWNTO 0) := (OTHERS => '0'); --counter output
BEGIN

  counter_set <= flipflops(0) xor flipflops(1);   --determine when to start/reset counter
  
  PROCESS(clk)
  BEGIN
    IF(clk'EVENT and clk = '1') THEN
      flipflops(0) <= button;
      flipflops(1) <= flipflops(0);
      If(counter_set = '1') THEN                  --reset counter because input is changing
        counter_out <= (OTHERS => '0');
      ELSIF(counter_out(counter_size) = '0') THEN --stable input time is not yet met
        counter_out <= counter_out + 1;
      ELSE                                        --stable input time is met
        result <= flipflops(1);
      END IF;    
    END IF;
  END PROCESS;
END logic;

Tutaj kod VHDL generatora krótkiego impulsu "monostable_ff.vhd":

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity monostable_ff is
 port(
      mono_pulse : out std_logic;		
      clk : in std_logic;  
      reset: in std_logic;  
      key :in  std_logic    
   );
end monostable_ff;

architecture Behavioral of monostable_ff is
	
	component DFF_AsyncReset is 
   port(
      Q : out std_logic;
      QNot : out std_logic;		
      clk : in std_logic;  
      reset: in std_logic;  
      D :in  std_logic    
      );
   end component;
	
	component nand2 is
   port(a,b : in std_logic; 
       y : out std_logic); 
   end component;
	
	signal Q1,Q2,Q3,Q4,Q5 : std_logic;
   signal Q1N,Q2N,Q3N,Q4N,Q5N : std_logic;
	signal s11 : std_logic;

begin

  DFF1: DFF_AsyncReset port map (                            
											  Q      => Q1,										 
		                             QNot   => Q1N,		
				                       clk    => clk,
				                       reset  => reset,
				                       D      => key   
                                 );
											
  DFF2: DFF_AsyncReset port map (                            
											  Q      => Q2,										 
		                             QNot   => Q2N,		
				                       clk    => clk,
				                       reset  => reset,
				                       D      => Q1   
                                 );	

  DFF3: DFF_AsyncReset port map (                            
											  Q      => Q3,										 
		                             QNot   => Q3N,		
				                       clk    => clk,
				                       reset  => reset,
				                       D      => Q2   
                                 );								
										
  DFF4: DFF_AsyncReset port map (                            
											  Q      => Q4,										 
		                             QNot   => Q4N,		
				                       clk    => clk,
				                       reset  => reset,
				                       D      => Q3  
                                 );	
											
  DFF5: DFF_AsyncReset port map (                            
											  Q      => Q5,										 
		                             QNot   => Q5N,		
				                       clk    => clk,
				                       reset  => reset,
				                       D      => Q4  
                                 );												
											
   mono_pulse <= (Q1 and Q5N);											
											
											
end Behavioral;

Układ jest zrobiony na "liniI opóźniającej" z kilku przerzutników typu D i dwu-wejściowej bramki "AND" (kiedyś w mojej przeszłości budowało się podobne układy na układach scalonych z serii TTL). Do budowy tego generatora monostabilnego użyłem przerzutników typu D (wejście zegarowe reaguje na zbocze narastające) z asynchronicznym resetem stanem niskim. Tutaj kod przerzutnika typu D

----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

-- Uncomment the following library declaration if using
-- arithmetic functions with Signed or Unsigned values
--use IEEE.NUMERIC_STD.ALL;

-- Uncomment the following library declaration if instantiating
-- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;

entity DFF_AsyncReset is 
   port(
      Q : out std_logic;
      QNot : out std_logic;		
      clk : in std_logic;  
      reset: in std_logic;  
      D :in  std_logic    
   );
end DFF_AsyncReset;

architecture Behavioral of DFF_AsyncReset is  
begin  
 process(clk,reset)
 begin 
     if(reset='0') then 
      Q <= '0';
		QNot <= '1';
     elsif(rising_edge(clk)) then
      Q <= D; 
      QNot <= (not D);
  end if;      
 end process;  
end Behavioral;

A tutaj plik "user constraints" "lw-spi_master.ucf" dla zestawu Elbert v.2:

CONFIG VCCAUX = "3.3" ;
 
# Clock 12 MHz
NET "clk_i"             LOC = P129  | IOSTANDARD = LVCMOS33 | PERIOD = 12MHz;

NET "en_i_Low"          LOC = P80   | PULLUP  | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 12; #SW1

#	mosi_data_i 	: in  STD_LOGIC_VECTOR (7 downto 0); DIPSwitch
NET "mosi_data_i[7]"        LOC = P70   | PULLUP  | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 12;
NET "mosi_data_i[6]"        LOC = P69   | PULLUP  | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 12;
NET "mosi_data_i[5]"        LOC = P68   | PULLUP  | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 12;
NET "mosi_data_i[4]"        LOC = P64   | PULLUP  | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 12;
NET "mosi_data_i[3]"        LOC = P63   | PULLUP  | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 12;
NET "mosi_data_i[2]"        LOC = P60   | PULLUP  | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 12;
NET "mosi_data_i[1]"        LOC = P59   | PULLUP  | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 12;
NET "mosi_data_i[0]"        LOC = P58   | PULLUP  | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 12;

#	miso_data_o 	: out STD_LOGIC_VECTOR (7 downto 0); LEDs
NET "miso_data_o[7]"             LOC = P46   | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 12;
NET "miso_data_o[6]"             LOC = P47   | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 12;
NET "miso_data_o[5]"             LOC = P48   | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 12;
NET "miso_data_o[4]"             LOC = P49   | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 12;
NET "miso_data_o[3]"             LOC = P50   | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 12;
NET "miso_data_o[2]"             LOC = P51   | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 12;
NET "miso_data_o[1]"             LOC = P54   | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 12;
NET "miso_data_o[0]"             LOC = P55   | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 12;

####################################################################################################
# HEADER P1
####################################################################################################

#	sclk_o 			: out STD_LOGIC;
NET "sclk_o"       LOC = P31   | IOSTANDARD = LVCMOS33 | SLEW = FAST | DRIVE = 12; #1

#	mosi_o 			: out STD_LOGIC;
NET "mosi_o"       LOC = P32   | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 12; #2

#	miso_i 			: in  STD_LOGIC
NET "miso_i"       LOC = P28   | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 12; #3

#	cs_o 			   : out STD_LOGIC;
NET "cs_o"         LOC = P30   | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 12; #4 

#	data_ready_o 	: out STD_LOGIC;
NET "data_ready_o" LOC = P27   | IOSTANDARD = LVCMOS33 | SLEW = SLOW | DRIVE = 12; #5

#Port ( 
#	clk_i 			: in  STD_LOGIC;
#	en_i_Low 			   : in  STD_LOGIC;
#	mosi_data_i 	: in  STD_LOGIC_VECTOR (7 downto 0);
#	miso_data_o 	: out STD_LOGIC_VECTOR (7 downto 0);
#	data_ready_o 	: out STD_LOGIC;
#	cs_o 			   : out STD_LOGIC;
#	sclk_o 			: out STD_LOGIC;
#	mosi_o 			: out STD_LOGIC;
#	miso_i 			: in  STD_LOGIC
#);

Jak widać w pliku dane (bajt), które są wysyłane magistralą SPI do Arduino UNO, są podłączone do 8-miu DIP Switchy z zestawu Elbert, a przycisk "SW1" powoduje jednorazowa wysyłkę bajtu danych. Tutaj zrzut ekranu z "monitora portu szeregowego" z ARDUINO IDE z programem do odbioru danych po SPI.:

SPI_Reader_Arduino_.thumb.png.768e67ffd06a6e899d776cd391dc92fe.png

Na koniec wklejam spakowany zip'em projekt dla Xilinx "ISE 14.7". Implementacja całego projektu zajmuje poniżej 100 LUT. Wklejam opis projektu bo takie funkcje komunikacyjne przydają się w przyszłości do bardziej skomplikowanych projektów. Teraz pozostaje uruchomienie kodu na zestawie FPGA "Sipeed Tang nano 4K".

LW_SPI_master_01.zip

Pozdrawiam

Edytowano przez FlyingDutch
  • Lubię! 2
Link do komentarza
Share on other sites

Zapomniałem dodać kod programu na "Arduino UNO" (SPI Slave) do odbioru danych z FPGA - robię to teraz:

// ====================================================================
// Arduino code example for SPI Slave Mode
// Read unsigned short (two bytes) from SPI, send word to serial port
// On 16 MHz Arduino, can work at > 500 words per second
// J.Beale July 19 2011
// ====================================================================

#define SCK_PIN   13  // D13 = pin19 = PortB.5
#define MISO_PIN  12  // D12 = pin18 = PortB.4
#define MOSI_PIN  11  // D11 = pin17 = PortB.3
#define SS_PIN    10  // D10 = pin16 = PortB.2

#define UL unsigned long
#define US unsigned short

void SlaveInit(void) {
  // Set MISO output, all others input
  pinMode(SCK_PIN, INPUT);
  pinMode(MOSI_PIN, INPUT);
  pinMode(MISO_PIN, OUTPUT);  // (only if bidirectional mode needed)
  pinMode(SS_PIN, INPUT);

  /*  Setup SPI control register SPCR
  SPIE - Enables the SPI interrupt when 1
  SPE - Enables the SPI when 1
  DORD - Sends data least Significant Bit First when 1, most Significant Bit first when 0
  MSTR - Sets the Arduino in master mode when 1, slave mode when 0
  CPOL - Sets the data clock to be idle when high if set to 1, idle when low if set to 0
  CPHA - Samples data on the trailing edge of the data clock when 1, leading edge when 0
  SPR1 and SPR0 - Sets the SPI speed, 00 is fastest (4MHz) 11 is slowest (250KHz)   */
  
  // enable SPI subsystem and set correct SPI mode
  // SPCR = (1<<SPE)|(0<<DORD)|(0<<MSTR)|(0<<CPOL)|(0<<CPHA)|(0<<SPR1)|(1<<SPR0); 
}

// SPI status register: SPSR
// SPI data register: SPDR

// ================================================================
// read in short as two bytes, with high-order byte coming in first
// ================================================================
unsigned short Read2Bytes(void) {
    union {
    unsigned short svar;
    byte c[2];
  } w;        // allow access to 2-byte word, or separate bytes
  
  while(!(SPSR & (1<<SPIF))) ; // SPIF bit set when 8 bits received
  w.c[1] = SPDR;               // store high-order byte
  while(!(SPSR & (1<<SPIF))) ; // SPIF bit set when 8 bits received
  w.c[0] = SPDR;               // store low-order byte
  return (w.svar); // send back unsigned short value
}


void setup() {
  Serial.begin(115200);
  SlaveInit();  // set up SPI slave mode
  delay(10);
  Serial.println("SPI port reader v0.1"); 
}

// ============================================================
// main loop: read in short word (2 bytes) from external SPI master
// and send value out via serial port
// On 16 MHz Arduino, works at > 500 words per second
// ============================================================
void loop() {
  unsigned short word1;
  byte flag1;
  byte tab[2];
  byte *B_ptr;

     // SS_PIN = Digital_10 = ATmega328 Pin 16 =  PORTB.2
    // Note: digitalRead() takes 4.1 microseconds
    // NOTE: SS_PIN cannot be properly read this way while SPI module is active!
    while (digitalRead(SS_PIN)==1) {} // wait until SlaveSelect goes low (active)
    
    SPCR = (1<<SPE)|(0<<DORD)|(0<<MSTR)|(0<<CPOL)|(0<<CPHA)|(0<<SPR1)|(1<<SPR0); // SPI on
    word1 = Read2Bytes();          // read unsigned short value
    SPCR = (0<<SPE)|(0<<DORD)|(0<<MSTR)|(0<<CPOL)|(0<<CPHA)|(0<<SPR1)|(1<<SPR0);  // SPI off
    //---------------------------------------
    byte low = (word1 & 0xFF);
    byte high = (word1 >> 8) & 0xFF;
    
//    float seconds = millis()/1000.0;  // time stamp takes more serial time, of course
//    Serial.print(seconds,3);   
//    Serial.print(",");
    
    Serial.print(high);
    Serial.print("\t");
    Serial.print(low);
    Serial.println();

}  // end loop()

Pozdrawiam

  • Lubię! 2
Link do komentarza
Share on other sites

Bądź aktywny - zaloguj się lub utwórz konto!

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto w ~20 sekund!

Zarejestruj nowe konto, to proste!

Zarejestruj się »

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się »
×
×
  • Utwórz nowe...

Ważne informacje

Ta strona używa ciasteczek (cookies), dzięki którym może działać lepiej. Więcej na ten temat znajdziesz w Polityce Prywatności.