<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="da">
	<id>https://www.htxarduino.dk/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Bar</id>
	<title>HTX Arduino - Brugerbidrag [da]</title>
	<link rel="self" type="application/atom+xml" href="https://www.htxarduino.dk/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Bar"/>
	<link rel="alternate" type="text/html" href="https://www.htxarduino.dk/index.php/Speciel:Bidrag/Bar"/>
	<updated>2026-08-17T14:33:38Z</updated>
	<subtitle>Brugerbidrag</subtitle>
	<generator>MediaWiki 1.45.1</generator>
	<entry>
		<id>https://www.htxarduino.dk/index.php?title=Spole_ved_AC&amp;diff=5431</id>
		<title>Spole ved AC</title>
		<link rel="alternate" type="text/html" href="https://www.htxarduino.dk/index.php?title=Spole_ved_AC&amp;diff=5431"/>
		<updated>2026-04-20T13:01:34Z</updated>

		<summary type="html">&lt;p&gt;Bar: /* Faseforskydning */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Fil:Electronic_component_inductors.jpg|thumb]] &lt;br /&gt;
&lt;br /&gt;
En spole vil prøve at forhindre enhver ændring i dens strøm. Sendes strøm igennem den vil den prøve at forhindre strømmen i at opstå, og modsat vil den forsøge at fastholde strømmen hvis den fjernes.&lt;br /&gt;
&lt;br /&gt;
Denne evne kaldes for selvinduktion (L), som måles i Henry (H).&lt;br /&gt;
&lt;br /&gt;
Vi vil se på en spole forbundet til en vekselspændingskilde:&lt;br /&gt;
Skruer vi ned for frekvensen vil strømmen stige og omvendt. Det er fordi under hyppige strømændringer vil spolen inducere en modsat spænding over sig, og altså forhindre strømmen i at ændre sig. Energien til dette får den ved at nedbryde sit magnetfelt.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spolen yder en stigende modstand, ved stigende frekvens.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Reaktans ==&lt;br /&gt;
&lt;br /&gt;
Spolen optræder som en vekselstrømsmodstand også kaldet en reaktans (X&amp;lt;sub&amp;gt;L&amp;lt;/sub&amp;gt;), som måles i ohm. Reaktansen er ligefrem proportional med frekvensen. Fordobles frekvensen, fordobles reaktansen.&lt;br /&gt;
&lt;br /&gt;
En spole med større selvinduktion vil også få reaktansen til at stige:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;X&amp;lt;sub&amp;gt;L&amp;lt;/sub&amp;gt; = 2*π*f*L&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Reaktansen for en ideel spole kan beregnes efter Ohms lov:&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;X&amp;lt;sub&amp;gt;L&amp;lt;/sub&amp;gt; = u&amp;lt;sub&amp;gt;L&amp;lt;/sub&amp;gt;/i&amp;lt;sub&amp;gt;L&amp;lt;/sub&amp;gt;&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Faseforskydning ==&lt;br /&gt;
[[Fil:Spole_Faseforskydning.png|thumb]]&lt;br /&gt;
&lt;br /&gt;
En spole har ligesom en kondensator også en faseforskydning imellem strøm og spænding. I Spolen kommer spændingen (e i figuren) 90° før strømmen (i i figuren), hvor det er omvendt i en kondensator. De 90° svarer til 1/4 af periodetiden.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Spændingen kommer 90° (1/4 periode) før strømmen.&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Magnetfeltet er i fase med strømmen. Eftersom det er strømændringen, der får spolen til at inducere sin spolespænding u&amp;lt;sub&amp;gt;e&amp;lt;/sub&amp;gt;, vil spændingen være størst når strømændringen er størst. Det er den lige ved nulskæringen, da kurven er stejlest netop der.&lt;br /&gt;
&lt;br /&gt;
== Eksempel på udregning ==&lt;br /&gt;
&lt;br /&gt;
For en spole på 0,1 H findes X&amp;lt;sub&amp;gt;L&amp;lt;/sub&amp;gt; ved 100 Hz til:&lt;br /&gt;
 &#039;&#039;&#039;X&amp;lt;sub&amp;gt;L&amp;lt;/sub&amp;gt; = 2*π*f*L = 2*π*100Hz*0,1H = 62,8 Ω&#039;&#039;&#039;&lt;br /&gt;
Ved 1000 Hz vil X&amp;lt;sub&amp;gt;L&amp;lt;/sub&amp;gt; blive 10 gange større. En spole på 1 H vil ligeledes have en 10 gange større modstand ved denne frekvens.&lt;br /&gt;
&lt;br /&gt;
På en spole måles spænding og strøm til 3 V og 1,5 mA, ved frekvensen 1 kHz.&lt;br /&gt;
 &#039;&#039;&#039;X&amp;lt;sub&amp;gt;L&amp;lt;/sub&amp;gt; = u/i = 3V/1,5mA = 2 kΩ&#039;&#039;&#039;&lt;br /&gt;
Så findes selvinduktion:&lt;br /&gt;
 &#039;&#039;&#039;X&amp;lt;sub&amp;gt;L&amp;lt;/sub&amp;gt; = 2*π*f*L &amp;lt;=&amp;gt; L = X&amp;lt;sub&amp;gt;L&amp;lt;/sub&amp;gt;/(2*π*f) = 2kΩ/(2*π*1kHz) = 0,32 H&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
== Spolens godhed ==&lt;br /&gt;
En spole er ofte viklet af kobbertråd, og vil derfor have en ohmsk modstand der afhænger af trådens tykkelse og længde. Kernen kan også yde andre tab. Samlet kaldes alle disse tab for spolens tabsmodstand &#039;&#039;&#039;r&#039;&#039;&#039;. På grund af denne tabsmodstand er fasedrejningen ikke længere 90gr (ikke en ideel spole). &lt;br /&gt;
Spolens godhed &#039;&#039;&#039;Q&#039;&#039;&#039;, angiver forholdet imellem induktiv reaktans og tabsmodstanden.&lt;br /&gt;
 &#039;&#039;&#039;Q = X&amp;lt;sub&amp;gt;L&amp;lt;/sub&amp;gt;/r&lt;br /&gt;
&lt;br /&gt;
== Selvinduktion ==&lt;br /&gt;
&lt;br /&gt;
En [[:Kategori:spole|spole]]s selvinduktionen bestemmes af fire egenskaber:&lt;br /&gt;
*Spolens vindingers diameter&lt;br /&gt;
*Antallet af vindinger&lt;br /&gt;
*Spolens bredde&lt;br /&gt;
*Materialet der tjener som evt. &amp;quot;kerne&amp;quot; i spolen.&lt;br /&gt;
&lt;br /&gt;
{{analog}}&lt;br /&gt;
&lt;br /&gt;
[[Kategori:Spole]]&lt;br /&gt;
[[Kategori:Filtre]]&lt;/div&gt;</summary>
		<author><name>Bar</name></author>
	</entry>
	<entry>
		<id>https://www.htxarduino.dk/index.php?title=Arduino_Transceiver_modul&amp;diff=5430</id>
		<title>Arduino Transceiver modul</title>
		<link rel="alternate" type="text/html" href="https://www.htxarduino.dk/index.php?title=Arduino_Transceiver_modul&amp;diff=5430"/>
		<updated>2025-12-31T23:17:04Z</updated>

		<summary type="html">&lt;p&gt;Bar: /* Forbedring af rækkevidden */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Fil:2-4-transiver.jpg|thumb|right|300px|2.4 GHz Transceiver modul (NRF24L01)]]&lt;br /&gt;
&lt;br /&gt;
NRF24L01 er et modul, der kan bruges til at sende og modtage data fra en microcontroller til en anden. &amp;lt;br&amp;gt;&lt;br /&gt;
Dette betyder, at modulet både kan bruges som transmitter og receiver. Men det skal dog stadigvæk have klare instrukser om, hvilket af de to stadier den skal være i, altså om den skal sende eller modtage, så derfor er to vejs kommunikation ikke så lige til, som f.eks. bluetooth er.&lt;br /&gt;
&lt;br /&gt;
Selve modulet kører på 2.4 GHz båndet, hvilket er det samme som de fleste wifi kommunikationer. Modulet er i stand til at levere data med 2 Mbps, hvilket er forholdsvist meget, for en så lille og billig chip. &amp;lt;br&amp;gt;&lt;br /&gt;
Modulet har et meget lavt strømforbrug, da det maksimalt bruger 14 mA, samt har en &amp;quot;standby&amp;quot; funktion, hvilket bruger få µA. Dette gør modulet ideelt til projekter, som kører på batteri.&lt;br /&gt;
&lt;br /&gt;
Uddybende information om modulet kan findes her &amp;lt;ref&amp;gt;[http://arduinoinfo.mywikis.net/wiki/Nrf24L01-2.4GHz-HowTo Uddybende information] om modulet på engelsk&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Databladet for modulet kan findes på Nordic Semiconducter&#039;s hjemmeside &amp;lt;ref&amp;gt;[http://www.nordicsemi.com/eng/Products/2.4GHz-RF/nRF24L01 Datablad] fra producent&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Modulet kan skaffes forskellige steder &amp;lt;ref&amp;gt;[http://www.miniinthebox.com/upgraded-2-4ghz-nrf24l01-wireless-transceiver-module-for-arduino-black_p683437.html Købsside] ved MiniInTheBox.com&amp;lt;/ref&amp;gt; &amp;lt;ref&amp;gt;[https://www.aliexpress.com/item/DIP-NRF24L01-wireless-data-transmission-module-2-4G-NRF24L01-wireless-module/32817243166.html Købsside] ved aliexpress.com&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
__FORCETOC__&lt;br /&gt;
&lt;br /&gt;
== Uddybende information om NRF24L01 ==&lt;br /&gt;
&lt;br /&gt;
=== Forskellige versioner ===&lt;br /&gt;
[[Fil:NRF24L01-ANT.jpg|thumb|right|200px|NRF24L01 med ekstern antenne]]&lt;br /&gt;
&lt;br /&gt;
NRF24L01 modulerne, er en serie af billige RF moduler, baseret på &amp;quot;Nordic Semiconductor nRF24L01+&amp;quot; chippen.&lt;br /&gt;
&lt;br /&gt;
De findes i flere forskellige versioner. Både med indbyggede antenner i printpladen (low-power version) og eksterne antenner (high-power version). De mest almindelige og billigste er dem med antennen indbygget i printpladen. Disse opnår dog ikke en rækkevidde, som er nær så lang som dem med eksterne antenner.&lt;br /&gt;
&lt;br /&gt;
===Rækkevidde===&lt;br /&gt;
&lt;br /&gt;
Modulerne med indbygget antenne, reklameres med at have en rækkevidde op til 100 meter. Dette er dog, under meget optimale forhold. Dette vil sige udenfor, uden nogen forhindringer og med en solid strømkilde. Derudover vil man heller ikke kunne bruge de fulde 2 Mbps, hvis man vil opnå så stor rækkevidde med low-power versionen. Indenfor vil man igennem mure kunne opnå ca. 10 meter. Der er dog visse ting, der kan gøre, for at gøre rækkevidden bedre. Dette vil der stå mere om, under afsnittet [[#Forbedring af rækkevidden|forbedring af rækkevidden]]&lt;br /&gt;
&lt;br /&gt;
Med den eksterne antenne, vil man med nogle moduler kunne opnå en rækkevidde på op til 1 km.&lt;br /&gt;
&lt;br /&gt;
{{#ev:youtube|gtM832Z0ujE|400}}&amp;lt;br /&amp;gt;&lt;br /&gt;
[https://youtu.be/gtM832Z0ujE Her] ses en video af youtuberen &amp;quot;iforce2d&amp;quot;, som laver en sammenligning af rækkevidden på nogle forskellige moduler:&lt;br /&gt;
&lt;br /&gt;
Han har også lavet et forsøg, hvor han formåede at få en rækkevidde på over 31 km, med et NRF24L01 modul, med en stor antenne. Det er ca den samme afstand, som der er fra Holstebro og til Herning.&lt;br /&gt;
&lt;br /&gt;
== Brug af NRF24L01 ==&lt;br /&gt;
&lt;br /&gt;
===Biblioteker===&lt;br /&gt;
Der findes flere forskellige biblioteker til modulet, som alle sammen gør det meget nemmer at benytte det ellers meget komplekse modul. Det mest udførlige, samt det bibliotek der vil blive brugt i eksemplerne er TMRh20&#039;s RF24 bibliotek. Det kan findes i Arduinoens IDE under Sketch - Include Library - Manage Libraries... Søg der efter &amp;quot;RF24&amp;quot; og led efter biblioteket fra TMRh20. Eller download biblioteket fra github. &amp;lt;ref&amp;gt;[http://tmrh20.github.io/RF24/ TMRh20&#039;s RF24 bibliotek] på Github&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Opkobling af modul (Hardware) ===&lt;br /&gt;
Det er meget vigtigt, at være klar over, at modulet kører på 3.3V(1.9 til 3.6V) og ikke 5V, som ellers er normalt for de fleste arduino moduler! Heldigvis er alle data benene 5V tolerante, hvilket betyder, at de kan kobles direkte op til arduinoens data pins.&lt;br /&gt;
&lt;br /&gt;
Det kan være besværligt, at finde ud af, hvilke pins der skal hvortil første gang man bruger modulet, men en let måde at kende det på, er ved at kigge efter den firkantede solder pad. Dette er pin 1, hvorefter de tæller opad i 4 rækker.&amp;lt;br&amp;gt;&lt;br /&gt;
Dette billede viser modulet set oppefra. &amp;lt;br&amp;gt;&lt;br /&gt;
[[Fil:24L01Pinout.jpg|700px]]&lt;br /&gt;
&lt;br /&gt;
Det er muligt at ændre på de to pins CE og CSN i programmet man skriver, hvilket vil sige, at de kan bruges på andre pins i stedet. Men SCK, MOSI og MISO er bestemt efter, hvilke pins modulet, som man kobler sin NRF op til, bruger til SPI kommunikation.&lt;br /&gt;
&lt;br /&gt;
Der er en del forskellige måder at koble modulet op, alt efter hvilket library man bruger. &lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Ben!!Navn!!Note!!TMRh20-RF24!!RF24!!Mirf!!RH_NRF24!!RF24(Mega)!!RH_NRF24(Mega)&lt;br /&gt;
|-&lt;br /&gt;
|1||GND||Stel||GND||GND||GND||GND||GND||GND&lt;br /&gt;
|-&lt;br /&gt;
|2||VCC||3.3V!||3.3V*||3.3V*||3.3V*||3.3V*||3.3V*||3.3V*&lt;br /&gt;
|-&lt;br /&gt;
|3||CE||-||7||9||8||8||9||8&lt;br /&gt;
|-&lt;br /&gt;
|4||CSN||-||8||10||7||10||53||53&lt;br /&gt;
|-&lt;br /&gt;
|5||SCK||-||13||13||13||13||52||52&lt;br /&gt;
|-&lt;br /&gt;
|6||MOSI||-||11||11||11||11||51||51&lt;br /&gt;
|-&lt;br /&gt;
|7||MISO||-||12||12||12||12||50||50&lt;br /&gt;
|-&lt;br /&gt;
|8||IRQ||-||-**||2||-**||-**||2||-**&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Hvis man bruger TMRh20&#039;s bibliotek, kan andre moduler kobles op på følgende måde:&lt;br /&gt;
&lt;br /&gt;
{|class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Ben!!Navn!!Note!!Arduino UNO!!Arduino Mega!!ATtiny25/45/85!!ATtiny44/84!!RPi&lt;br /&gt;
|-&lt;br /&gt;
|1||GND||Stel||GND||GND||pin 4||pin 14||RPi-GND&lt;br /&gt;
|-&lt;br /&gt;
|2||VCC||3.3V!||3.3V*||3.3V*||pin 8||pin 1||RPi-3v3&lt;br /&gt;
|-&lt;br /&gt;
|3||CE||-||7||7||pin 2||pin 12||RPi-GPIO22&lt;br /&gt;
|-&lt;br /&gt;
|4||CSN||-||8||8||pin 3||pin 11||RPi-GPIO8&lt;br /&gt;
|-&lt;br /&gt;
|5||SCK||-||13||52||pin 7||pin 9||RPi-sckl&lt;br /&gt;
|-&lt;br /&gt;
|6||MOSI||-||11||51||pin 6||pin 7||RPi-mosi&lt;br /&gt;
|-&lt;br /&gt;
|7||MISO||-||12||50||pin 5||pin 8||RPi-miso&lt;br /&gt;
|-&lt;br /&gt;
|8||IRQ||-||-**||-**||-**||-**||-**&lt;br /&gt;
|}&lt;br /&gt;
&amp;lt;b&amp;gt;Bemærk! &amp;lt;/b&amp;gt;&amp;lt;i&amp;gt;Ved de to arduino boards, bliver der refereret til deres digitale outputs, mens de to ATtiny chips, refererer til deres respektive pins på selve microcontrolleren.&amp;lt;/i&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;* Grunden til mange problemer med modulet, er at arduinoens indbyggede 3.3V ikke kan give så meget strøm, som modulet har brug for under de meget korte sendinger af data. Arduino Mega&#039;en er det største problem. Læs mere om dette problem, og hvordan man løser det under [[#Forbedring af rækkevidden|forbedring af rækkevidden]] &amp;lt;br&amp;gt;&lt;br /&gt;
Dette betyder ikke, at man ikke kan bruge de indbyggede 3.3V fra arduinoen. Man kan bare ikke forvente lige så gode resultater. &amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;p&amp;gt;** Det er ikke alle biblioteker, der benytter sig af IRQ, men RF24 biblioteket benytter sig af det i nogle eksempler. &amp;lt;/p&amp;gt;&lt;br /&gt;
&lt;br /&gt;
=== Sending af data (Software) ===&lt;br /&gt;
==== Kommandoer ====&lt;br /&gt;
Der findes et hav af kommandoer til dette modul, som alle kan findes på TMRH20&#039;s side for modulet. &amp;lt;ref&amp;gt;[https://tmrh20.github.io/RF24/classRF24.html Liste] over kommandoer for modulet&amp;lt;/ref&amp;gt;&lt;br /&gt;
Dog vil der kun blive gennemgået de basale, så det er muligt at få modulet op at køre.&lt;br /&gt;
&lt;br /&gt;
Det først der skal gøres, er at starte en ny radio. Dette skal gøres både på afsender og modtager modulet. I dette tilfælde kalder vi den bare &amp;quot;radio&amp;quot;, men den kan også hedde hvad som helst andet. Det er også her vi definerer hvilke pins, der skal bruges til hhv. CE og CS.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
//Overordnet definition af kommando:&lt;br /&gt;
RF24 nameOfRadio(CEPIN, CSPIN); //nameOfRadio kan udskiftes med lige hvad man vil, og bruges i andre kommandoer, når man bruger modulet. uint8_t _cepin og uint8_t _cspin bestemmer hvilke pins man bruger som hhv. CE og CS pins.&lt;br /&gt;
//Eksempel:&lt;br /&gt;
RF24 radio(7,8); //I vores eksempel kalder vi radioen for radio og vi bruger pin 7 som CE og pin 8 som CS.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nu hvor vi har kaldt vores radio &amp;quot;radio&amp;quot;, skal dette indgå i kommandoer, når vi bruger modulet. Dette gøre ved at skrive &amp;quot;radio&amp;quot; efterfulgt af et punktum, og derefter kommandoen man vil udføre.&lt;br /&gt;
&lt;br /&gt;
For at kunne benytte vores modul, skal det først startes. Dette gøres med med følgende kommando:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
//Overordnet definition af kommando:&lt;br /&gt;
nameOfRadio.begin(); //Indsæt navnet på din radio på nameOfRadio&#039;s plads&lt;br /&gt;
//Eksempel:&lt;br /&gt;
radio.begin(); //I dette tilfælde benytter vi vores navn &amp;quot;radio&amp;quot;, som valgte i kommandoen ovenfor.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Det er også muligt at indstille hastigheden, hvorved modulet overfører data til et andet modul. Grunden til, at dette er brugbart, forklares i sektionen med [[#Forbedring af rækkevidden|forbedring af rækkevidden]]. For at indstille hastigheden, skal følgende kommando bruges:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
//Overordnet definition af kommando:&lt;br /&gt;
nameOfRadio.setDataRate(RF24_DATARATE); //I parenteserne, skal datahastigheden indsættes. Der er 3 forskellige muligheder.&lt;br /&gt;
//Eksempel:&lt;br /&gt;
radio.setDataRate(RF24_250KBPS);  //Sæt data hastigheden til 250 Kbps, for at opnå maksimal rækkevidde.&lt;br /&gt;
radio.setDataRate(RF24_1MBPS);  //Sæt data hastigheden til 1 Mbps, for at opnå middel hastighed og rækkevidde.&lt;br /&gt;
radio.setDataRate(RF24_2MBPS); //Sæt data hastigheden til 2 Mbps, for at opnå maksimal hastighed.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Derudover er det også muligt at indstille, hvor meget strøm modulet bruger. Brugbarhede naf dette forklares under [[#Forbedring af rækkevidden|forbedring af rækkevidden]]. For at benytte sig af funktionen, benyttes følgende kommando:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
//Overordnet definition af kommando:&lt;br /&gt;
nameOfRadio.setPALevel(RF24_POWER); //I parenteserne, skal strømniveauet af modulet sættes til et af de 4 følgende værdier.&lt;br /&gt;
//Eksempel:&lt;br /&gt;
radio.setPALevel(RF24_PA_MIN); //Sæt strømniveauet for modulet til det minimale&lt;br /&gt;
radio.setPALevel(RF24_PA_LOW); //Sæt strømniveauet for modulet til lav&lt;br /&gt;
radio.setPALevel(RF24_PA_HIGH); //Sæt strømniveauet for modulet til høj&lt;br /&gt;
radio.setPALevel(RF24_PA_MAX); //Sæt strømniveauet for modulet til det maksimale&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der skal vælges en kanal, som de moduler kan snakke over. Det er vigtigt, at den kanal man bruger, ikke bliver brugt af alt muligt andet udstyr, som kan lave interferens. Denne kanal kan gå fra 0 til 124, så det vil sige 125 forskellige kanaler. Under [[#Forbedring af rækkevidden|forbedring af rækkevidden]] står der mere om, hvorfor det er vigtigt at vælge den rigtige kanal. Kommandoen fungerer som følger:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
//Overordnet definition af kommando:&lt;br /&gt;
nameOfRadio.setChannel(CHANNEL_NUMBER); //Kanalen sættes til et tal mellem 0 og 124.&lt;br /&gt;
//Eksempel:&lt;br /&gt;
radio.setChannel(108); //I dette eksempel sættes kanalen til 108.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For at kommunikerer imellem de to moduler, skal der først laves et &amp;quot;rør&amp;quot; (pipe), som de to moduler kan snakke igennem. Dette rør, skal have en fælles adresse, kanal og datahastighed, for at de to moduler kan snakke sammen.&lt;br /&gt;
&lt;br /&gt;
For at sende informationer, skal der åbnes et &amp;quot;skrive rør&amp;quot; (writing pipe). Dette gøres ved først at definere en adresse, og derefter lave et &amp;quot;skrive rør&amp;quot; med denne adresse på sendermodulet:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
//Overordnet definition af kommando:&lt;br /&gt;
byte addresses[][6] = {ADDRESS}; //Indsæt den valgte adresse i ADDRESS.&lt;br /&gt;
nameOfRadio.openWritingPipe(addresses[0]); //Her er adressen indsat i kommandoen.&lt;br /&gt;
//Eksempel:&lt;br /&gt;
byte addresses[][6] = {&amp;quot;0&amp;quot;}; //I dette eksempel er adressen sat til &amp;quot;0&amp;quot;.&lt;br /&gt;
radio.openWritingPipe(addresses[0]); //Adressen er indsat i kommandoen&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Nu skal der tilsvarende også være et &amp;quot;læse rør&amp;quot; (reading pipe). Dette gøres på næsten samme måde, som med &amp;quot;skrive røret&amp;quot;. Den eneste forskel er, at der skal et tal ind som en anden parameter i kommandoen. Følgende kommando skal stå i koden for modtagermodulet:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
//Overordnet definition af kommando:&lt;br /&gt;
byte addresses[][6] = {ADDRESS}; //Indsæt den valgte adresse i ADDRESS.&lt;br /&gt;
nameOfRadio.openReadingPipe(1, addresses[0]); //Her er tallet 1, samt adressen indsat i kommandoen.&lt;br /&gt;
//Eksempel:&lt;br /&gt;
byte addresses[][6] = {&amp;quot;0&amp;quot;}; //I dette eksempel er adressen sat til &amp;quot;0&amp;quot;.&lt;br /&gt;
radio.openReadingPipe(1, addresses[0]); //Her er tallet 1, samt adressen indsat i kommandoen.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
En anden meget vigtig kommando for modtager modulet er kommandoen der får modulet til at lytte:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
//Overordnet definition af kommando:&lt;br /&gt;
nameOfRadio.startListening(); //Får modulet til at begynde at lytte.&lt;br /&gt;
//Eksempel:&lt;br /&gt;
radio.startListening(); //Får modulet til at begynde at lytte.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For at sende noget til det andet modul, skal bestemme hvad for noget data der skal sendes, og hvor stor dataet er:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
//Overordnet definition af kommando:&lt;br /&gt;
nameOfRadio.write(&amp;amp;DATA, sizeof(SIZE_OF_DATA); //Den første parameter skal være et &amp;amp; tegn, efterfulgt af det data der skal sendes, og den anden parameter skal være størrelsen af den type data.&lt;br /&gt;
//Eksempel:&lt;br /&gt;
int test = 42; //42 bliver gemt i variablen test.&lt;br /&gt;
radio.write(&amp;amp;test, sizeof(int); //42 bliver sendt, ved at sætte et &amp;amp; tegn foran variablen test&#039;s navn. Den anden parameter er størrelsen på en int.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
For at modtage data fra det andet modul, skal der gøres stort set det samme.&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
//Overordnet definition af kommando:&lt;br /&gt;
nameOfRadio.read(&amp;amp;DATA, sizeof(SIZE_OF_DATA); //Den første parameter skal være et &amp;amp; tegn, efterfulgt af det data der skal modtages, og den anden parameter skal være størrelsen af den type data.&lt;br /&gt;
//Eksempel:&lt;br /&gt;
int test; //Der allokeres plads til en int ved navn test,&lt;br /&gt;
radio.read(&amp;amp;test, sizeof(int); // Der bliver modtaget noget og gemt i variablen test.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;I&amp;gt;Dette er alle kommandoer der skal til, for at opbygge en simpel et vejs kommunikation. For at lave mere avancerede programmer, kan man bruge den fulde liste af kommandoer, samt nogle af de andre [[#Referencer|referencer]] der er linket til i bunden af siden.&amp;lt;/I&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Eksempel ====&lt;br /&gt;
Dette er et eksempel på et meget simpelt program, der sender noget data i en pakke fra et modul til et andet. Koden er skrevet af &amp;quot;educ8s.tv&amp;quot;, som også har lavet en kort video, som forklarer de grundlæggende ting ved modulet.&amp;lt;ref&amp;gt;[http://educ8s.tv/nrf24l01/ educ8s.tv&#039;s hjemmeside] om NRF24L01&amp;lt;/ref&amp;gt;&lt;br /&gt;
Koden til modulet, samt biblioteket på daværende tidspunkt kan findes [[:File:nrf24l01eksempel.zip|her]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Sender modul:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;SPI.h&amp;gt; //Der skal bruges SPI for at kommunikere med modult.&lt;br /&gt;
#include &amp;quot;RF24.h&amp;quot; //Biblioteket for modulet tages i brug.&lt;br /&gt;
&lt;br /&gt;
RF24 myRadio (7, 8); //Der laves en radio ved navn &amp;quot;myRadio&amp;quot;, der benytter sig af pin 7 og 8.&lt;br /&gt;
byte addresses[][6] = {&amp;quot;0&amp;quot;}; //Adressen &amp;quot;0&amp;quot; benyttes til at kommunikere.&lt;br /&gt;
&lt;br /&gt;
struct package //Der laves en struktur med data i.&lt;br /&gt;
{&lt;br /&gt;
  int id = 1; //Nummer på pakken der bliver sendt.&lt;br /&gt;
  float temperature = 18.3; //Fiktiv temperatur, der illustrerer at man kan sende flere forskellige typer af data på en gang.&lt;br /&gt;
  char  text[100] = &amp;quot;Text to be transmitted&amp;quot;; //Tekst der bliver sendt med hver pakke.&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
typedef struct package Package;&lt;br /&gt;
Package data; //Pakken bliver kaldt &amp;quot;data&amp;quot;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
void setup()&lt;br /&gt;
{&lt;br /&gt;
  Serial.begin(115200); //Der startes en seriel kommunikation med en båndbredde på 115200.&lt;br /&gt;
  delay(1000); //Der er et delay på 1 sekund.&lt;br /&gt;
  myRadio.begin(); //Radioen ved navn &amp;quot;myRadio&amp;quot; startes.&lt;br /&gt;
  myRadio.setChannel(115); //Kanalen bliver sat til 115&lt;br /&gt;
  myRadio.setPALevel(RF24_PA_MAX); //Strømniveauet for modulet bliver sat til MAX. (Dette gøres kun, da der bliver brugt en solid strømkilde.)&lt;br /&gt;
  myRadio.setDataRate(RF24_250KBPS) ; //Båndbredden bliver sat til 250 KBPS, da der ikke skal bruges mere end det, for at sende de 3 typer data.&lt;br /&gt;
  myRadio.openWritingPipe(addresses[0]); //Der startes et &amp;quot;skrive rør&amp;quot; med adressen, som blev sat til 0 tidligere.&lt;br /&gt;
  delay(1000); //Endnu et delay på 1 sekund.&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop()&lt;br /&gt;
{&lt;br /&gt;
  myRadio.write(&amp;amp;data, sizeof(data)); //Pakken ved navn data bliver afsendt.&lt;br /&gt;
&lt;br /&gt;
  Serial.print(&amp;quot;\nPackage:&amp;quot;); //Et linjeskift efterfulgt af &amp;quot;Package:&amp;quot; bliver skrevet til den serielle monitor.&lt;br /&gt;
  Serial.println(data.id); //Id i pakken data bliver skrevet til den serielle monitor.&lt;br /&gt;
  Serial.println(data.temperature); //Den fiktive temperatur bliver skrevet til den serielle monitor.&lt;br /&gt;
  Serial.println(data.text); //Teksten bliver skrevet til den serielle monitor.&lt;br /&gt;
  data.id++; //Id i pakken data bliver gjort 1 større.&lt;br /&gt;
  data.temperature += 0.1; //Den fiktive temperatur bliver gjort 0.1 større.&lt;br /&gt;
  delay(1000); //Der ventes i 1 sekund.&lt;br /&gt;
&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Modtager modul&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;SPI.h&amp;gt; //Der skal bruges SPI for at kommunikere med modult.&lt;br /&gt;
#include &amp;quot;RF24.h&amp;quot; //Biblioteket for modulet tages i brug.&lt;br /&gt;
&lt;br /&gt;
RF24 myRadio (7, 8); //Der laves en radio ved navn &amp;quot;myRadio&amp;quot;, der benytter sig af pin 7 og 8.&lt;br /&gt;
&lt;br /&gt;
byte addresses[][6] = {&amp;quot;0&amp;quot;}; //Adressen &amp;quot;0&amp;quot; benyttes til at kommunikere.&lt;br /&gt;
&lt;br /&gt;
struct package //Der laves en struktur med data i&lt;br /&gt;
{&lt;br /&gt;
  int id; //Der gøres plads til en int ved navn &amp;quot;id&amp;quot;&lt;br /&gt;
  float temperature; //Der gøres plads til en float ved navn &amp;quot;temperature&amp;quot;&lt;br /&gt;
  char  text[100]; //Der gøres plads til en char ved navn &amp;quot;text&amp;quot;&lt;br /&gt;
};&lt;br /&gt;
&lt;br /&gt;
typedef struct package Package;&lt;br /&gt;
Package data; //Pakken bliver kaldt &amp;quot;data&amp;quot;&lt;br /&gt;
&lt;br /&gt;
void setup() &lt;br /&gt;
{&lt;br /&gt;
  Serial.begin(115200); //Der startes en seriel kommunikation med en båndbredde på 115200.&lt;br /&gt;
  delay(1000); //Der er et delay på 1 sekund.&lt;br /&gt;
  myRadio.begin(); //Radioen ved navn &amp;quot;myRadio&amp;quot; startes.&lt;br /&gt;
  myRadio.setChannel(115); //Kanalen bliver sat til 115.&lt;br /&gt;
  myRadio.setPALevel(RF24_PA_MAX); //Strømniveauet for modulet bliver sat til MAX. (Dette gøres kun, da der bliver brugt en solid strømkilde.)&lt;br /&gt;
  myRadio.setDataRate(RF24_250KBPS); //Båndbredden bliver sat til 250 KBPS, da der ikke skal bruges mere end det, for at sende de 3 typer data.&lt;br /&gt;
  myRadio.openReadingPipe(1, addresses[0]); //Der startes et &amp;quot;læse rør&amp;quot; med adressen, som blev sat til 0 tidligere.&lt;br /&gt;
  myRadio.startListening(); //Modulet bliver sat til at lytte efter data.&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop()  &lt;br /&gt;
{&lt;br /&gt;
&lt;br /&gt;
  if (myRadio.available()) //Gør følgende, hvis der er data til rådighed.&lt;br /&gt;
  {&lt;br /&gt;
    while (myRadio.available()) //Gør følgende, så længe der er data til rådighed.&lt;br /&gt;
    {&lt;br /&gt;
      myRadio.read( &amp;amp;data, sizeof(data) ); //Læs data der er til rådighed og gem den i strukturen data.&lt;br /&gt;
    }&lt;br /&gt;
    Serial.print(&amp;quot;\nPackage:&amp;quot;); //Et linjeskift efterfulgt af &amp;quot;Package:&amp;quot; bliver skrevet til den serielle monitor.&lt;br /&gt;
    Serial.println(data.id); //Id i pakken data bliver skrevet til den serielle monitor.&lt;br /&gt;
    Serial.println(data.temperature); //Den fiktive temperatur bliver skrevet til den serielle monitor.&lt;br /&gt;
    Serial.println(data.text); //Teksten bliver skrevet til den serielle monitor.&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;I&amp;gt;Det er klart anbefalet at uploade koden til sender modulet fra en computer og koden til modtager modulet fra en anden, da man på den måde nemmere kan overskue den serielle monitor fra begge moduler.&amp;lt;/I&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Forbedring af rækkevidden===&lt;br /&gt;
[[Fil:Nrf24l01-socket-8-pin.jpg|thumb|right|250px|NRF24L01 socket]]&lt;br /&gt;
Der kan gøres en række ting, for at forbedre rækkenvidden af NRF24L01 modulet:&lt;br /&gt;
* Den mest mærkbare ting, er at bruge en pålidelig 3.3V strømforsyning. Dette skyldes, at modulet bruger forholdsvist meget strøm i de meget korte øjeblikke, hvor den den sender data, selvom den alt i alt har et meget lavt strømforbrug. Arduinoen er nemlig kun i stand til at give 50 mA ved 3.3V. En løsning kan være, at bruge en anden strømforsyning eller bruge en bedre 3.3V regulator, til formindske arduinoens 5V, hvilket kan give rigeligt med strøm. Dette kan gøres, ved at bruge en såkaldt &amp;quot;NRF24L01 socket&amp;quot;. Med dette modul er det muligt at bruge arduinoens 5V, mens det derudover også er nemmere at koble modulet til.&lt;br /&gt;
* En anden ting, der kan være med til at lave en mærkbar forskel, er at sætte en kondensator fra GND til VCC, så modulet kan suge lidt ekstra strøm, i de korte øjeblikke den har brug for det. Dette kan enten gøres på et breadboard, på en printplade, eller bare ved at lodde den direkte på modulet (Vær opmærksom på polaritet). Det er anbefalet at bruge en kondensator på mellem 3.3 og 10 µF. Nogle brugere har dog også haft meget god succes, med en kombination af en 10µF i parallel forbindelse med en 0.1µF kondensator.&lt;br /&gt;
* For at få så lang rækkevidde, som overhovedet muligt, er det en god idé, at sætte modulets strømniveau til det maksimale. Dette er dog kun, hvis den har mulighed for at benytte sig af så meget strøm, som den har brug for. Indtil man har en solid forbindelse, mellem to moduler, med en kort afstand imellem dem, er det en god idé at sætte strømniveauet til det minimale, og så derefter sætte det op. For at indstille strømniveuet, skal man skrive en af følgende fire kommandoer ind i setup:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
radio.setPALevel(RF24_PA_MIN); //Sæt strømniveauet for modulet til det minimale&lt;br /&gt;
radio.setPALevel(RF24_PA_LOW); //Sæt strømniveauet for modulet til lav&lt;br /&gt;
radio.setPALevel(RF24_PA_HIGH); //Sæt strømniveauet for modulet til høj&lt;br /&gt;
radio.setPALevel(RF24_PA_MAX); //Sæt strømniveauet for modulet til det maksimale&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* Hvis man ikke har brug for, at benytte sig af de fulde 2 Mbps, som modulet kan levere, kan man opnå en smule bedre rækkevidde, ved at begrænse hastigheden, hvorved dataen bliver sendt. Dette skal også indsættes i setup:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
radio.setDataRate(RF24_250KBPS);  //Sæt data hastigheden til 250 Kbps, for at opnå minimal rækkevidde.&lt;br /&gt;
radio.setDataRate(RF24_1MBPS);  //Sæt data hastigheden til 1 Mbps, for at opnå middel hastighed og rækkevidde.&lt;br /&gt;
radio.setDataRate(RF24_2MBPS); //Sæt data hastigheden til 2 Mbps, for at opnå maksimal hastighed.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
* Modulet er i stand til at bruge en frekvens på mellem 2.4 GHz og 2.525 GHz. Dette betyder, at man kan undgå den frekvens, som mange Wifi-netværk og Bluetooth apparater benytter sig af, nemlig ~ 2.4GHz. Modulet har 125 mulige kanaler, med 1 MHz mellemrum imellem dem. De 25 højeste kanaler, er anbefalet at bruge. Hvis man er i tvivl om, hvilken kanal der er bedst at bruge, kan man benytte sig af &amp;quot;scanner&amp;quot; eksemplet, som kigger efter interferens på de forskellige kanaler. For at benytte en kanal, skal følgende kommando bruges i setup:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
radio.setChannel(CHANNEL_NUMBER); //Indsæt den valgte kanal fra 0 til 124 på pladsen CHANNEL_NUMBER.&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Scanner eksemplet i Tmrh20&#039;s bibliotek virker ved at se efter, hvilke kanaler der bliver brugt meget, altså hvilke kanaler man vil opleve meget interferens på, hvis man benytter dem. Det kan godt være lidt forvirrende at finde ud af, hvad det, som programmet skriver i den serielle moniter skal betyde, men når man først forstår opsætningen er det meget nemt at finde ud af. Det skal ses som en tabel, hvor der er en masse lodrette rækker. De to første linjer er kanalen skrevet lodret i hex, så hvis der f.eks. står 3a, vises interferensen for kanal 58 lodret ned (da dette er det decimale tal for 33 i hex, da hex er et 16 base talsystem). De forskellige tal, der vises er hvor meget interferens der er på kanalen i hex. Så jo nærmere 0, jo bedre.&lt;br /&gt;
Nedenfor ses et eksempel på et serielt output for scanner programmet:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
RF24/examples/scanner/&lt;br /&gt;
000000000000000011111111111111112222222222222222333333333333333344444444444444445555555555555555666666666666666677777777777777&lt;br /&gt;
0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcd&lt;br /&gt;
011111000000122112311010122211233101123222001110000000010000132576445000000221111000000000000000000000000000000000000000000000&lt;br /&gt;
001000120010210025320122211120220100000000012111000000024553366456444000001000112000000000000000000000000000000000000000000000&lt;br /&gt;
001000000012211000101010112211111222322000011111111000036532354653000000001110112000000000000000000000000000000000000000000000&lt;br /&gt;
121100000121111100001111221000132121011000000002210000034321120220000000002221001100000000000000000000000000000000000000000000&lt;br /&gt;
000011110001221111111110113331011111200011001320000000034343653562554020000001310000000000000000000000000000000000000000000000&lt;br /&gt;
010111102111000121000002442211100112214422210100000000100003476a97465400000000121000000000000000000000000000000000000000000000&lt;br /&gt;
000000002413420001001001100011211101212433101010000001044565775677634010000000101000000000000000000000000000000000000000000000&lt;br /&gt;
001321021211111100111110122201001000000111100010011000055445763432010000000011010100000000000000000000000000000000000000000000&lt;br /&gt;
000100022211200110010000002032323310013211000001211000042200330112000010000011110100000000000000000000000000000000000000000000&lt;br /&gt;
000100011121012122011000134530001220000233100000110000000000120234345001000012223100000000000000000000000000000000000000000000&lt;br /&gt;
001000012121012332211120011112221111121222211110221000000023665876675010000000011000000000000000000000000000000000000000000000&lt;br /&gt;
014320001332113210010100131144110011121000000001000000155555564668432100000021122100000000000000000000000000000000000000000000&lt;br /&gt;
010211022320101122232110212101111000110001101111000001025444751332100110001121100000000000000000000000000000000000000000000000&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
Som det kan ses, er kanalen 52 i hex (82 i decimal) og opefter ikke i brug. Disse ville derfor være optilmale til at bruge. Der er også nogle enkelte huller ind imellem som f.eks. kanal 33 i hex (51 i decimal).&lt;br /&gt;
&lt;br /&gt;
==Referencer==&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Arduino-Modul-Oversigt}}&lt;br /&gt;
&lt;br /&gt;
[[Kategori:Arduino Moduler]]&lt;/div&gt;</summary>
		<author><name>Bar</name></author>
	</entry>
	<entry>
		<id>https://www.htxarduino.dk/index.php?title=Printfremstilling&amp;diff=5429</id>
		<title>Printfremstilling</title>
		<link rel="alternate" type="text/html" href="https://www.htxarduino.dk/index.php?title=Printfremstilling&amp;diff=5429"/>
		<updated>2025-12-27T16:55:41Z</updated>

		<summary type="html">&lt;p&gt;Bar: /* Video med forklaringer */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Kort huskeliste==&lt;br /&gt;
# Belys 2:00 - 3:00 (husk at tekst skal ende med at være læselig)&lt;br /&gt;
# Fremkald i 0,4M NaOH&lt;br /&gt;
# Skyl, aftør og bor 2mm hul&lt;br /&gt;
# Æts i Natriumpersulfat til banerne står frit&lt;br /&gt;
# Skyl og aftør&lt;br /&gt;
# Belys 2:00 - 3:00&lt;br /&gt;
# Fremkald i 0,4M NaOH&lt;br /&gt;
# Bor huller efter komponentbenene 0,8mm, 1,0mm, 1,3mm&lt;br /&gt;
&lt;br /&gt;
==Generelt om printfremstilling==&lt;br /&gt;
&lt;br /&gt;
Et print er en række lederbaner på et isolerende materiale. Tit bruger man den engelske betegnelse PCB (Print Circuit Board). Print kan til simplere formål fremstilles ved hjælp af en fotografisk proces, med efterfølgende ætsning.&lt;br /&gt;
&lt;br /&gt;
Det rå print er en glasfiber-base med et kobberlag på den ene side (begge sider, hvis det skal være til dobbeltsidet). På dette kobberlag er der et lysfølsomt lag, der er specielt følsom over for ultraviolet lys. Dette lag er beskyttet af et lag papir, der ikke kan trænge lys igennem (heller ikke ultraviolet).&lt;br /&gt;
&lt;br /&gt;
Mønsteret der skal overføres til printet skal være på en positiv film, altså en film der kan lyses igennem med et sort mønster hvor der skal være printbaner.&lt;br /&gt;
&lt;br /&gt;
For at fremstille layoutet skal det printes på en passende film. Layoutet kan typisk fremstilles i [[:kategori:Eagle|Eagle]], hvor man starter i sit [[Schematics|Schematic]], hvor man skal vælge det fysiske komponenter der skal placeres på printet. Når man har tegnet hele diagrammet, så skal man placere komponenter og baner i [[Layout|PCB-Layout]], der også er en del af Eagle.&lt;br /&gt;
&lt;br /&gt;
Fremkaldelsen af printet har den virkning at de dele der er blevet belyst, kan fjernes ved hjælp af natriumhydroxyd. Det der så er tilbage skal dække for kobberet, så det kun er de steder hvor der ikke skal være baner, at der ætses.&lt;br /&gt;
&lt;br /&gt;
Ætsebadet er en opløsning af Natriumpersulfat (finætsekrystal), der arbejder ved hjælp af bobler. Den ætsende virkning kommer ved at persulfat-ionerne er så kraftigt oxiderende, at de er i stand til at trække det metalliske kobber ud i væsken, hvilket kan ses ved at væsken, der i starten er farveløs, får en klar blå farve.&lt;br /&gt;
&lt;br /&gt;
==Om kemikalier.==&lt;br /&gt;
Ved arbejde med kemikalier bør man undgå hud- og øjenkontakt. Det anbefales at anvende gummihandsker og straks søge læge, hvis kemikalierne kommer i øjnene.&lt;br /&gt;
&lt;br /&gt;
Kemikalier skal opbevares utilgængeligt for børn.&lt;br /&gt;
&lt;br /&gt;
Beholdere med kemikalier skal mærkes med hvad de indeholder, og man skal orientere sig omkring de forskellige kemikaliers egenskaber (der hænger beskrivelser i ætse rummet).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Belysning af Printet.==&lt;br /&gt;
Printet klippes til så det passer efter filmen, beregn ca. 0,5 mm ekstra, da de yderste kanter kan få beskadiet det lysfølsomme lag, ved klipning af printet.&lt;br /&gt;
&lt;br /&gt;
Filmen placeres på glaspladen i lyskassen, så teksterne er spejlvendt, og printet med den lysfølsomme side ned mod filmen (husk at pille papiret af), og placeres så banerne ikke berører kanterne af printet. Låget til lyskassen lukkes og spændes til, så der er optimal kontakt mellem film og print.&lt;br /&gt;
&lt;br /&gt;
Belys printet i ca. 3 minutter (300 på timeren). Timeren starter ved tryk på instillingsknappen. Hvis printet er ved at være gammelt, så kan det reddes ved at forøge belysningstiden til 4 minutter.&lt;br /&gt;
&lt;br /&gt;
==Fremkaldelse af printet.==&lt;br /&gt;
Printet fremkaldes i en 0,4 M opløsning af NaOH (12g pr. liter). Opløsningen er basisk og ætsende.&lt;br /&gt;
&lt;br /&gt;
Fremkald printet i en fotobakke, ved at hælde ca. 200ml i bakken og bevæge væsken, så man kan se hvordan fremkaldeprocessen skrider frem. Anvend evt. en fin pensel til at fremskynde processen, men pas på ikke at ridse den lysfølsomme film.&lt;br /&gt;
&lt;br /&gt;
Fremkaldelsen tager ca. ½ minut.&lt;br /&gt;
&lt;br /&gt;
Skyl printet godt under vandhanen (pas på ikke at ridse printet).&lt;br /&gt;
&lt;br /&gt;
Brugt fremkalder hældes i basisk affald.&lt;br /&gt;
&lt;br /&gt;
==Ætsning af printet.==&lt;br /&gt;
Printet ætses i Natriumpersulfat (koncentration 200 g/liter). Natriumpersulfat er ætsende og affarver tøjet - det ses normalt ikke før tøjet er vasket.&lt;br /&gt;
&lt;br /&gt;
[http://www.cypax.com/pdf/natriumpersulfat_rev.pdf Kemikalie-beskrivelse af Natriumpersulfat].&lt;br /&gt;
&lt;br /&gt;
Der bores et 2mm hul et sted i printet hvor det ikke betyder noget.&lt;br /&gt;
&lt;br /&gt;
Printet placeres midt i printholderen så man kan se kobbersiden. Anvend plast-isoleret ledning til at placere printet fornuftigt i ætsekarret – ætsetiden fremskyndes ved at boblerne passerer hen over printet.&lt;br /&gt;
&lt;br /&gt;
Hvis ætsetiden kommer over 30 minutter i varm tilstand er væskens ætseevne ved at være brugt op og skal udskiftes. Brugt ætsevæske hældes i surt affald.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Efterbehandling af printet.==&lt;br /&gt;
Resterne af det lysfølsomme lag fjernes ved at belyse igen (3 minutter uden film), og fremkalde det lysfølsomme lag af kobberbanerne.&lt;br /&gt;
&lt;br /&gt;
Printet bores med de størrelser huller der passer til komponentbenene (0,8mm 1,0mm og 1,3mm).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==RYD FOR H . . . . . .  OP==&lt;br /&gt;
Fremkalderbakken tømmes og fremkalderen i kommes basisk affald. Fremkalderbakken skylles grundigt .&lt;br /&gt;
&lt;br /&gt;
Ætsemaskinen tildækkes så væsken ikke fordamper, og der slukkes for strømmen.&lt;br /&gt;
&lt;br /&gt;
Alt stilles på plads, og bordet tørres af.&lt;br /&gt;
&lt;br /&gt;
==Video med forklaringer==&lt;br /&gt;
&lt;br /&gt;
Printfremstilling laves på professionel vis, og hovedparten produceres i Kina - her er lige en film der viser hele processen, når man skal lave dobbeltsidet print med loddemaske og silketryk.&amp;lt;br /&amp;gt;&lt;br /&gt;
{{#ev:youtube|_GVk_hEMjzs}}&amp;lt;br /&amp;gt;&lt;br /&gt;
[https://www.youtube.com/watch?v=_GVk_hEMjzs Direkte link]&lt;br /&gt;
&lt;br /&gt;
Jeg har venligst fået lov til at inkludere disse to videoer fra John Ellekrogh der arbejder på Viby HTX.&lt;br /&gt;
&lt;br /&gt;
Det er ikke alle materialer og tider der passer præcist, men det er en god omtale af teknikken.&lt;br /&gt;
&lt;br /&gt;
Teknikken omkring kring det at få fremstillet filmen til et printudlæg&amp;lt;br /&amp;gt;&lt;br /&gt;
{{#ev:youtube|vZEVSyKoho8}}&amp;lt;br /&amp;gt;&lt;br /&gt;
[https://www.youtube.com/watch?v=vZEVSyKoho8 Direkte link]&lt;br /&gt;
&lt;br /&gt;
Teknikken om at få belyst, fremkaldt og ætset sit print, så det er klar til boring&amp;lt;br /&amp;gt;&lt;br /&gt;
{{#ev:youtube|Bx6s034CoqM}}&amp;lt;br /&amp;gt;&lt;br /&gt;
[http://youtu.be/Bx6s034CoqM Direkte link]&lt;br /&gt;
&lt;br /&gt;
Noget af processen igen, med lidt andre kommentarer og tider - helt frem til at printet er loddet&amp;lt;br /&amp;gt;&lt;br /&gt;
{{#ev:youtube|EDJmKeOch9o}}&amp;lt;br /&amp;gt;&lt;br /&gt;
[https://www.youtube.com/watch?v=EDJmKeOch9o Direkte link]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Elektronik-Montage}}&lt;br /&gt;
&lt;br /&gt;
[[Kategori:Elektronik_Montage]]&lt;br /&gt;
[[Kategori:værkstedet]]&lt;br /&gt;
[[Kategori:Hardware Udviklingsteknikker]]&lt;/div&gt;</summary>
		<author><name>Bar</name></author>
	</entry>
	<entry>
		<id>https://www.htxarduino.dk/index.php?title=Printfremstilling&amp;diff=5428</id>
		<title>Printfremstilling</title>
		<link rel="alternate" type="text/html" href="https://www.htxarduino.dk/index.php?title=Printfremstilling&amp;diff=5428"/>
		<updated>2025-12-27T16:52:53Z</updated>

		<summary type="html">&lt;p&gt;Bar: /* Video med forklaringer */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;==Kort huskeliste==&lt;br /&gt;
# Belys 2:00 - 3:00 (husk at tekst skal ende med at være læselig)&lt;br /&gt;
# Fremkald i 0,4M NaOH&lt;br /&gt;
# Skyl, aftør og bor 2mm hul&lt;br /&gt;
# Æts i Natriumpersulfat til banerne står frit&lt;br /&gt;
# Skyl og aftør&lt;br /&gt;
# Belys 2:00 - 3:00&lt;br /&gt;
# Fremkald i 0,4M NaOH&lt;br /&gt;
# Bor huller efter komponentbenene 0,8mm, 1,0mm, 1,3mm&lt;br /&gt;
&lt;br /&gt;
==Generelt om printfremstilling==&lt;br /&gt;
&lt;br /&gt;
Et print er en række lederbaner på et isolerende materiale. Tit bruger man den engelske betegnelse PCB (Print Circuit Board). Print kan til simplere formål fremstilles ved hjælp af en fotografisk proces, med efterfølgende ætsning.&lt;br /&gt;
&lt;br /&gt;
Det rå print er en glasfiber-base med et kobberlag på den ene side (begge sider, hvis det skal være til dobbeltsidet). På dette kobberlag er der et lysfølsomt lag, der er specielt følsom over for ultraviolet lys. Dette lag er beskyttet af et lag papir, der ikke kan trænge lys igennem (heller ikke ultraviolet).&lt;br /&gt;
&lt;br /&gt;
Mønsteret der skal overføres til printet skal være på en positiv film, altså en film der kan lyses igennem med et sort mønster hvor der skal være printbaner.&lt;br /&gt;
&lt;br /&gt;
For at fremstille layoutet skal det printes på en passende film. Layoutet kan typisk fremstilles i [[:kategori:Eagle|Eagle]], hvor man starter i sit [[Schematics|Schematic]], hvor man skal vælge det fysiske komponenter der skal placeres på printet. Når man har tegnet hele diagrammet, så skal man placere komponenter og baner i [[Layout|PCB-Layout]], der også er en del af Eagle.&lt;br /&gt;
&lt;br /&gt;
Fremkaldelsen af printet har den virkning at de dele der er blevet belyst, kan fjernes ved hjælp af natriumhydroxyd. Det der så er tilbage skal dække for kobberet, så det kun er de steder hvor der ikke skal være baner, at der ætses.&lt;br /&gt;
&lt;br /&gt;
Ætsebadet er en opløsning af Natriumpersulfat (finætsekrystal), der arbejder ved hjælp af bobler. Den ætsende virkning kommer ved at persulfat-ionerne er så kraftigt oxiderende, at de er i stand til at trække det metalliske kobber ud i væsken, hvilket kan ses ved at væsken, der i starten er farveløs, får en klar blå farve.&lt;br /&gt;
&lt;br /&gt;
==Om kemikalier.==&lt;br /&gt;
Ved arbejde med kemikalier bør man undgå hud- og øjenkontakt. Det anbefales at anvende gummihandsker og straks søge læge, hvis kemikalierne kommer i øjnene.&lt;br /&gt;
&lt;br /&gt;
Kemikalier skal opbevares utilgængeligt for børn.&lt;br /&gt;
&lt;br /&gt;
Beholdere med kemikalier skal mærkes med hvad de indeholder, og man skal orientere sig omkring de forskellige kemikaliers egenskaber (der hænger beskrivelser i ætse rummet).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Belysning af Printet.==&lt;br /&gt;
Printet klippes til så det passer efter filmen, beregn ca. 0,5 mm ekstra, da de yderste kanter kan få beskadiet det lysfølsomme lag, ved klipning af printet.&lt;br /&gt;
&lt;br /&gt;
Filmen placeres på glaspladen i lyskassen, så teksterne er spejlvendt, og printet med den lysfølsomme side ned mod filmen (husk at pille papiret af), og placeres så banerne ikke berører kanterne af printet. Låget til lyskassen lukkes og spændes til, så der er optimal kontakt mellem film og print.&lt;br /&gt;
&lt;br /&gt;
Belys printet i ca. 3 minutter (300 på timeren). Timeren starter ved tryk på instillingsknappen. Hvis printet er ved at være gammelt, så kan det reddes ved at forøge belysningstiden til 4 minutter.&lt;br /&gt;
&lt;br /&gt;
==Fremkaldelse af printet.==&lt;br /&gt;
Printet fremkaldes i en 0,4 M opløsning af NaOH (12g pr. liter). Opløsningen er basisk og ætsende.&lt;br /&gt;
&lt;br /&gt;
Fremkald printet i en fotobakke, ved at hælde ca. 200ml i bakken og bevæge væsken, så man kan se hvordan fremkaldeprocessen skrider frem. Anvend evt. en fin pensel til at fremskynde processen, men pas på ikke at ridse den lysfølsomme film.&lt;br /&gt;
&lt;br /&gt;
Fremkaldelsen tager ca. ½ minut.&lt;br /&gt;
&lt;br /&gt;
Skyl printet godt under vandhanen (pas på ikke at ridse printet).&lt;br /&gt;
&lt;br /&gt;
Brugt fremkalder hældes i basisk affald.&lt;br /&gt;
&lt;br /&gt;
==Ætsning af printet.==&lt;br /&gt;
Printet ætses i Natriumpersulfat (koncentration 200 g/liter). Natriumpersulfat er ætsende og affarver tøjet - det ses normalt ikke før tøjet er vasket.&lt;br /&gt;
&lt;br /&gt;
[http://www.cypax.com/pdf/natriumpersulfat_rev.pdf Kemikalie-beskrivelse af Natriumpersulfat].&lt;br /&gt;
&lt;br /&gt;
Der bores et 2mm hul et sted i printet hvor det ikke betyder noget.&lt;br /&gt;
&lt;br /&gt;
Printet placeres midt i printholderen så man kan se kobbersiden. Anvend plast-isoleret ledning til at placere printet fornuftigt i ætsekarret – ætsetiden fremskyndes ved at boblerne passerer hen over printet.&lt;br /&gt;
&lt;br /&gt;
Hvis ætsetiden kommer over 30 minutter i varm tilstand er væskens ætseevne ved at være brugt op og skal udskiftes. Brugt ætsevæske hældes i surt affald.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Efterbehandling af printet.==&lt;br /&gt;
Resterne af det lysfølsomme lag fjernes ved at belyse igen (3 minutter uden film), og fremkalde det lysfølsomme lag af kobberbanerne.&lt;br /&gt;
&lt;br /&gt;
Printet bores med de størrelser huller der passer til komponentbenene (0,8mm 1,0mm og 1,3mm).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==RYD FOR H . . . . . .  OP==&lt;br /&gt;
Fremkalderbakken tømmes og fremkalderen i kommes basisk affald. Fremkalderbakken skylles grundigt .&lt;br /&gt;
&lt;br /&gt;
Ætsemaskinen tildækkes så væsken ikke fordamper, og der slukkes for strømmen.&lt;br /&gt;
&lt;br /&gt;
Alt stilles på plads, og bordet tørres af.&lt;br /&gt;
&lt;br /&gt;
==Video med forklaringer==&lt;br /&gt;
&lt;br /&gt;
Printfremstilling laves på professionel vis, og hovedparten produceres i Kina - her er lige en film der viser hele processen, når man skal lave dobbeltsidet print med loddemaske og silketryk.&amp;lt;br /&amp;gt;&lt;br /&gt;
{{#ev:youtube|_GVk_hEMjzs}}&amp;lt;br /&amp;gt;&lt;br /&gt;
[https://www.youtube.com/watch?v=_GVk_hEMjzs Direkte link]&lt;br /&gt;
&lt;br /&gt;
Jeg har venligst fået lov til at inkludere disse to videoer fra John Ellekrogh der arbejder på Viby HTX.&lt;br /&gt;
&lt;br /&gt;
Det er ikke alle materialer og tider der passer præcist, men det er en god omtale af teknikken.&lt;br /&gt;
&lt;br /&gt;
Teknikken omkring kring det at få fremstillet filmen til et printudlæg&amp;lt;br /&amp;gt;&lt;br /&gt;
{{#ev:&amp;lt;youtube&amp;gt;|vZEVSyKoho8}}&amp;lt;br /&amp;gt;&lt;br /&gt;
[https://www.youtube.com/watch?v=vZEVSyKoho8 Direkte link]&lt;br /&gt;
&lt;br /&gt;
Teknikken om at få belyst, fremkaldt og ætset sit print, så det er klar til boring&amp;lt;br /&amp;gt;&lt;br /&gt;
{{#ev:youtube|Bx6s034CoqM}}&amp;lt;br /&amp;gt;&lt;br /&gt;
[http://youtu.be/Bx6s034CoqM Direkte link]&lt;br /&gt;
&lt;br /&gt;
Noget af processen igen, med lidt andre kommentarer og tider - helt frem til at printet er loddet&amp;lt;br /&amp;gt;&lt;br /&gt;
{{#ev:youtube|EDJmKeOch9o}}&amp;lt;br /&amp;gt;&lt;br /&gt;
[https://www.youtube.com/watch?v=EDJmKeOch9o Direkte link]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{Elektronik-Montage}}&lt;br /&gt;
&lt;br /&gt;
[[Kategori:Elektronik_Montage]]&lt;br /&gt;
[[Kategori:værkstedet]]&lt;br /&gt;
[[Kategori:Hardware Udviklingsteknikker]]&lt;/div&gt;</summary>
		<author><name>Bar</name></author>
	</entry>
	<entry>
		<id>https://www.htxarduino.dk/index.php?title=Breadboard&amp;diff=5427</id>
		<title>Breadboard</title>
		<link rel="alternate" type="text/html" href="https://www.htxarduino.dk/index.php?title=Breadboard&amp;diff=5427"/>
		<updated>2025-12-26T10:51:50Z</updated>

		<summary type="html">&lt;p&gt;Bar: /* Opbygning af opstillinger på Breadboard */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Et Breadboard (også kaldet fumlebræt) er designet til at opbygge simple kredsløb uden at lodde.&lt;br /&gt;
&lt;br /&gt;
Det oprindelige udtryk stammer fra den tidlige elektronik-tid, hvor man lavede simple kredsløb ved at slå søm i et skærebræt, og lodde komponenterne på sømhovederne.&lt;br /&gt;
&lt;br /&gt;
Det nuværende breadboard er noget simplere at anvende, da man blot kan stikke komponentbenene ned i hullerne, hvor der så er et net af forbindelser.&lt;br /&gt;
&lt;br /&gt;
Der findes forskellige størrelser, men et meget anvendt format et følgende:&lt;br /&gt;
&lt;br /&gt;
[[Fil:Breadboard_Udseende.png|400px|Udseende af typisk Breadboard med 2 x 30 rækker]]&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Udseende af typisk Breadboard med 2 x 30 rækker&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Forbindelserne i et Breadboard==&lt;br /&gt;
Nede i Breadboardet får komponenterne forbindelse med nogle metalskinner, der forbinder hullerne i en bestemt struktur.&lt;br /&gt;
&lt;br /&gt;
Der er typisk en eller to baner på hver side, som har forbindelse hele vejen hen gennem breadboardet. De er ofte markeret med + og -.&lt;br /&gt;
&lt;br /&gt;
Inde omkring midten ligger der forbindelser den modsatte vej, som går ud fra midten af breadboardet. &lt;br /&gt;
&lt;br /&gt;
Dette er illustreret herunder.&lt;br /&gt;
&lt;br /&gt;
[[Fil:Breadboard_Forbindelser.png|400px|Forbindelserne i et typisk Breadboard markeret med sorte streger]]&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Forbindelserne i et typisk Breadboard markeret med sorte streger&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
En anden type breadboard er fotograferet herunder.&lt;br /&gt;
&lt;br /&gt;
[[Fil:Breadboard_Foto.png|400px|Foto af en anden type Breadboard]]&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Foto af en anden type Breadboard&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For at vise hvordan forbindelserne er lavet, er der herunder vist et billede fra undersiden af breadboardet, hvor beskyttelsen er delvist pillet af.&lt;br /&gt;
&lt;br /&gt;
[[Fil:Breadboard_Bagside.png|400px|Det ovenstående Breadboard fotograferet fra bunden, med beskyttelsen fjernet]]&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Det ovenstående Breadboard fotograferet fra bunden, med beskyttelsen fjernet&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Opbygning af opstillinger på Breadboard==&lt;br /&gt;
&lt;br /&gt;
Layoutet af Breadboardet er lavet ud fra at IC&#039;er kan monteres i midten af breadboardet, så man får mange muligheder for forbindelser &lt;br /&gt;
&lt;br /&gt;
[[Fil:Breadboard_IC.png|150px|Placeringen af en IC i en del af et breadboard]]&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Placeringen af en IC i en del af et breadboard&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Herunder er vist hvordan man kan koble en opstilling op på et breadboard. Opstillingen er tegnet i [https://www.tinkercad.com/ www.TinkerCad.com], der i skrivende stund er et gratis værktøj fra Autodesk. Der ligger flere muligheder her, men dette kan tegnes inde under Circuits.&lt;br /&gt;
&lt;br /&gt;
[[Fil:Breadboard_Opstilling.png|800px|En opstilling på breadboard koblet sammen med en Arduino UNO]]&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;En opstilling på breadboard koblet sammen med en Arduino UNO&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Kredsløbet der er bygget på breadboard er en simpel transistor, der driver en lysdiode, som vist på diagrammet herunder.&lt;br /&gt;
&lt;br /&gt;
[[Fil:Breadboard_Diagram.png|800px|Diagram over ovenstående opstilling på breadboard]]&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Diagram over ovenstående opstilling på breadboard&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Komponenter der typisk anvendes sammen med Breadboard==&lt;br /&gt;
&lt;br /&gt;
Breadboards kan naturligvis anvendes generelt, men de bliver meget brugt sammen med [[Arduino_Hardware#Breadboard|Arduino Hardware]], hvor der også omtales nogle af de andre ting, det er en fordel at have for at komme i gang.&lt;br /&gt;
&lt;br /&gt;
{{Elektronik-Montage}}&lt;br /&gt;
&lt;br /&gt;
[[Kategori:Elektronik_Montage]]&lt;/div&gt;</summary>
		<author><name>Bar</name></author>
	</entry>
	<entry>
		<id>https://www.htxarduino.dk/index.php?title=Breadboard&amp;diff=5426</id>
		<title>Breadboard</title>
		<link rel="alternate" type="text/html" href="https://www.htxarduino.dk/index.php?title=Breadboard&amp;diff=5426"/>
		<updated>2025-12-26T10:51:31Z</updated>

		<summary type="html">&lt;p&gt;Bar: /* Opbygning af opstillinger på Breadboard */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Et Breadboard (også kaldet fumlebræt) er designet til at opbygge simple kredsløb uden at lodde.&lt;br /&gt;
&lt;br /&gt;
Det oprindelige udtryk stammer fra den tidlige elektronik-tid, hvor man lavede simple kredsløb ved at slå søm i et skærebræt, og lodde komponenterne på sømhovederne.&lt;br /&gt;
&lt;br /&gt;
Det nuværende breadboard er noget simplere at anvende, da man blot kan stikke komponentbenene ned i hullerne, hvor der så er et net af forbindelser.&lt;br /&gt;
&lt;br /&gt;
Der findes forskellige størrelser, men et meget anvendt format et følgende:&lt;br /&gt;
&lt;br /&gt;
[[Fil:Breadboard_Udseende.png|400px|Udseende af typisk Breadboard med 2 x 30 rækker]]&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Udseende af typisk Breadboard med 2 x 30 rækker&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Forbindelserne i et Breadboard==&lt;br /&gt;
Nede i Breadboardet får komponenterne forbindelse med nogle metalskinner, der forbinder hullerne i en bestemt struktur.&lt;br /&gt;
&lt;br /&gt;
Der er typisk en eller to baner på hver side, som har forbindelse hele vejen hen gennem breadboardet. De er ofte markeret med + og -.&lt;br /&gt;
&lt;br /&gt;
Inde omkring midten ligger der forbindelser den modsatte vej, som går ud fra midten af breadboardet. &lt;br /&gt;
&lt;br /&gt;
Dette er illustreret herunder.&lt;br /&gt;
&lt;br /&gt;
[[Fil:Breadboard_Forbindelser.png|400px|Forbindelserne i et typisk Breadboard markeret med sorte streger]]&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Forbindelserne i et typisk Breadboard markeret med sorte streger&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
En anden type breadboard er fotograferet herunder.&lt;br /&gt;
&lt;br /&gt;
[[Fil:Breadboard_Foto.png|400px|Foto af en anden type Breadboard]]&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Foto af en anden type Breadboard&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For at vise hvordan forbindelserne er lavet, er der herunder vist et billede fra undersiden af breadboardet, hvor beskyttelsen er delvist pillet af.&lt;br /&gt;
&lt;br /&gt;
[[Fil:Breadboard_Bagside.png|400px|Det ovenstående Breadboard fotograferet fra bunden, med beskyttelsen fjernet]]&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Det ovenstående Breadboard fotograferet fra bunden, med beskyttelsen fjernet&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Opbygning af opstillinger på Breadboard==&lt;br /&gt;
&lt;br /&gt;
Layoutet af Breadboardet er lavet ud fra at IC&#039;er kan monteres i midten af breadboardet, så man får mange muligheder for forbindelser &lt;br /&gt;
&lt;br /&gt;
[[Fil:Breadboard_IC.png|150px|Placeringen af en IC i en del af et breadboard]]&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Placeringen af en IC i en del af et breadboard&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Herunder er vist hvordan man kan koble en opstilling op på et breadboard. Opstillingen er tegnet i [https://www.tinkercad.com/ www.TinkerCad.com], der i skrivende stund er et gratis værktøj fra Autodesk. Der ligger flere muligheder her, men dette kan tegnes inde under Circuits.&lt;br /&gt;
&lt;br /&gt;
[[Fil:Breadboard_Opstilling.png|800px|En opstilling på breadboard koblet sammen med en Arduino UNO]]&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;En opstilling på breadboard koblet sammen med en Arduino UNO&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Kredsløbet der er bygget på breadboard er en simpel transistor, der driver en lysdiode, som vist på diagrammet herunder.&lt;br /&gt;
&lt;br /&gt;
[[Fil:Breadboard_Diagram.png|Diagram over ovenstående opstilling på breadboard]]&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Diagram over ovenstående opstilling på breadboard&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Komponenter der typisk anvendes sammen med Breadboard==&lt;br /&gt;
&lt;br /&gt;
Breadboards kan naturligvis anvendes generelt, men de bliver meget brugt sammen med [[Arduino_Hardware#Breadboard|Arduino Hardware]], hvor der også omtales nogle af de andre ting, det er en fordel at have for at komme i gang.&lt;br /&gt;
&lt;br /&gt;
{{Elektronik-Montage}}&lt;br /&gt;
&lt;br /&gt;
[[Kategori:Elektronik_Montage]]&lt;/div&gt;</summary>
		<author><name>Bar</name></author>
	</entry>
	<entry>
		<id>https://www.htxarduino.dk/index.php?title=Breadboard&amp;diff=5425</id>
		<title>Breadboard</title>
		<link rel="alternate" type="text/html" href="https://www.htxarduino.dk/index.php?title=Breadboard&amp;diff=5425"/>
		<updated>2025-12-26T10:34:19Z</updated>

		<summary type="html">&lt;p&gt;Bar: /* Opbygning af opstillinger på Breadboard */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Et Breadboard (også kaldet fumlebræt) er designet til at opbygge simple kredsløb uden at lodde.&lt;br /&gt;
&lt;br /&gt;
Det oprindelige udtryk stammer fra den tidlige elektronik-tid, hvor man lavede simple kredsløb ved at slå søm i et skærebræt, og lodde komponenterne på sømhovederne.&lt;br /&gt;
&lt;br /&gt;
Det nuværende breadboard er noget simplere at anvende, da man blot kan stikke komponentbenene ned i hullerne, hvor der så er et net af forbindelser.&lt;br /&gt;
&lt;br /&gt;
Der findes forskellige størrelser, men et meget anvendt format et følgende:&lt;br /&gt;
&lt;br /&gt;
[[Fil:Breadboard_Udseende.png|400px|Udseende af typisk Breadboard med 2 x 30 rækker]]&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Udseende af typisk Breadboard med 2 x 30 rækker&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Forbindelserne i et Breadboard==&lt;br /&gt;
Nede i Breadboardet får komponenterne forbindelse med nogle metalskinner, der forbinder hullerne i en bestemt struktur.&lt;br /&gt;
&lt;br /&gt;
Der er typisk en eller to baner på hver side, som har forbindelse hele vejen hen gennem breadboardet. De er ofte markeret med + og -.&lt;br /&gt;
&lt;br /&gt;
Inde omkring midten ligger der forbindelser den modsatte vej, som går ud fra midten af breadboardet. &lt;br /&gt;
&lt;br /&gt;
Dette er illustreret herunder.&lt;br /&gt;
&lt;br /&gt;
[[Fil:Breadboard_Forbindelser.png|400px|Forbindelserne i et typisk Breadboard markeret med sorte streger]]&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Forbindelserne i et typisk Breadboard markeret med sorte streger&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
En anden type breadboard er fotograferet herunder.&lt;br /&gt;
&lt;br /&gt;
[[Fil:Breadboard_Foto.png|400px|Foto af en anden type Breadboard]]&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Foto af en anden type Breadboard&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For at vise hvordan forbindelserne er lavet, er der herunder vist et billede fra undersiden af breadboardet, hvor beskyttelsen er delvist pillet af.&lt;br /&gt;
&lt;br /&gt;
[[Fil:Breadboard_Bagside.png|400px|Det ovenstående Breadboard fotograferet fra bunden, med beskyttelsen fjernet]]&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Det ovenstående Breadboard fotograferet fra bunden, med beskyttelsen fjernet&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Opbygning af opstillinger på Breadboard==&lt;br /&gt;
&lt;br /&gt;
Layoutet af Breadboardet er lavet ud fra at IC&#039;er kan monteres i midten af breadboardet, så man får mange muligheder for forbindelser &lt;br /&gt;
&lt;br /&gt;
[[Fil:Breadboard_IC.png|150px|Placeringen af en IC i en del af et breadboard]]&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Placeringen af en IC i en del af et breadboard&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Herunder er vist hvordan man kan koble en opstilling op på et breadboard. Opstillingen er tegnet i [https://www.tinkercad.com/ www.TinkerCad.com], der i skrivende stund er et gratis værktøj fra Autodesk. Der ligger flere muligheder her, men dette kan tegnes inde under Circuits.&lt;br /&gt;
&lt;br /&gt;
[[Fil:Breadboard_Opstilling.png|800px|En opstilling på breadboard koblet sammen med en Arduino UNO]]&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;En opstilling på breadboard koblet sammen med en Arduino UNO&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Kredsløbet der er bygget på breadboard er en simpel transistor, der driver en lysdiode, som vist på diagrammet herunder.&lt;br /&gt;
&lt;br /&gt;
[[Fil:Breadboard_Diagram.png|800px|Diagram over ovenstående opstilling på breadboard]]&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Diagram over ovenstående opstilling på breadboard&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Komponenter der typisk anvendes sammen med Breadboard==&lt;br /&gt;
&lt;br /&gt;
Breadboards kan naturligvis anvendes generelt, men de bliver meget brugt sammen med [[Arduino_Hardware#Breadboard|Arduino Hardware]], hvor der også omtales nogle af de andre ting, det er en fordel at have for at komme i gang.&lt;br /&gt;
&lt;br /&gt;
{{Elektronik-Montage}}&lt;br /&gt;
&lt;br /&gt;
[[Kategori:Elektronik_Montage]]&lt;/div&gt;</summary>
		<author><name>Bar</name></author>
	</entry>
	<entry>
		<id>https://www.htxarduino.dk/index.php?title=Breadboard&amp;diff=5424</id>
		<title>Breadboard</title>
		<link rel="alternate" type="text/html" href="https://www.htxarduino.dk/index.php?title=Breadboard&amp;diff=5424"/>
		<updated>2025-12-26T10:25:46Z</updated>

		<summary type="html">&lt;p&gt;Bar: /* Opbygning af opstillinger på Breadboard */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Et Breadboard (også kaldet fumlebræt) er designet til at opbygge simple kredsløb uden at lodde.&lt;br /&gt;
&lt;br /&gt;
Det oprindelige udtryk stammer fra den tidlige elektronik-tid, hvor man lavede simple kredsløb ved at slå søm i et skærebræt, og lodde komponenterne på sømhovederne.&lt;br /&gt;
&lt;br /&gt;
Det nuværende breadboard er noget simplere at anvende, da man blot kan stikke komponentbenene ned i hullerne, hvor der så er et net af forbindelser.&lt;br /&gt;
&lt;br /&gt;
Der findes forskellige størrelser, men et meget anvendt format et følgende:&lt;br /&gt;
&lt;br /&gt;
[[Fil:Breadboard_Udseende.png|400px|Udseende af typisk Breadboard med 2 x 30 rækker]]&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Udseende af typisk Breadboard med 2 x 30 rækker&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Forbindelserne i et Breadboard==&lt;br /&gt;
Nede i Breadboardet får komponenterne forbindelse med nogle metalskinner, der forbinder hullerne i en bestemt struktur.&lt;br /&gt;
&lt;br /&gt;
Der er typisk en eller to baner på hver side, som har forbindelse hele vejen hen gennem breadboardet. De er ofte markeret med + og -.&lt;br /&gt;
&lt;br /&gt;
Inde omkring midten ligger der forbindelser den modsatte vej, som går ud fra midten af breadboardet. &lt;br /&gt;
&lt;br /&gt;
Dette er illustreret herunder.&lt;br /&gt;
&lt;br /&gt;
[[Fil:Breadboard_Forbindelser.png|400px|Forbindelserne i et typisk Breadboard markeret med sorte streger]]&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Forbindelserne i et typisk Breadboard markeret med sorte streger&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
En anden type breadboard er fotograferet herunder.&lt;br /&gt;
&lt;br /&gt;
[[Fil:Breadboard_Foto.png|400px|Foto af en anden type Breadboard]]&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Foto af en anden type Breadboard&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For at vise hvordan forbindelserne er lavet, er der herunder vist et billede fra undersiden af breadboardet, hvor beskyttelsen er delvist pillet af.&lt;br /&gt;
&lt;br /&gt;
[[Fil:Breadboard_Bagside.png|400px|Det ovenstående Breadboard fotograferet fra bunden, med beskyttelsen fjernet]]&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Det ovenstående Breadboard fotograferet fra bunden, med beskyttelsen fjernet&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Opbygning af opstillinger på Breadboard==&lt;br /&gt;
&lt;br /&gt;
Layoutet af Breadboardet er lavet ud fra at IC&#039;er kan monteres i midten af breadboardet, så man får mange muligheder for forbindelser &lt;br /&gt;
&lt;br /&gt;
[[Fil:Breadboard_IC.png|150px|Placeringen af en IC i en del af et breadboard]]&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Placeringen af en IC i en del af et breadboard&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Herunder er vist hvordan man kan koble en opstilling op på et breadboard. Opstillingen er tegnet i [https://www.tinkercad.com/ www.TinkerCad.com], der i skrivende stund er et gratis værktøj fra Autodesk. Der ligger flere muligheder her, men dette kan tegnes inde under Circuits.&lt;br /&gt;
&lt;br /&gt;
[[Fil:Breadboard_Opstilling.png|800px|En opstilling på breadboard koblet sammen med en Arduino UNO]]&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;En opstilling på breadboard koblet sammen med en Arduino UNO&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Kredsløbet der er bygget på breadboard er en simpel transistor, der driver en lysdiode, som vist på diagrammet herunder.&lt;br /&gt;
&lt;br /&gt;
[[Fil:Breadboard_Diagram.png|Diagram over ovenstående opstilling på breadboard]]&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Diagram over ovenstående opstilling på breadboard&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Komponenter der typisk anvendes sammen med Breadboard==&lt;br /&gt;
&lt;br /&gt;
Breadboards kan naturligvis anvendes generelt, men de bliver meget brugt sammen med [[Arduino_Hardware#Breadboard|Arduino Hardware]], hvor der også omtales nogle af de andre ting, det er en fordel at have for at komme i gang.&lt;br /&gt;
&lt;br /&gt;
{{Elektronik-Montage}}&lt;br /&gt;
&lt;br /&gt;
[[Kategori:Elektronik_Montage]]&lt;/div&gt;</summary>
		<author><name>Bar</name></author>
	</entry>
	<entry>
		<id>https://www.htxarduino.dk/index.php?title=Breadboard&amp;diff=5423</id>
		<title>Breadboard</title>
		<link rel="alternate" type="text/html" href="https://www.htxarduino.dk/index.php?title=Breadboard&amp;diff=5423"/>
		<updated>2025-12-26T10:22:55Z</updated>

		<summary type="html">&lt;p&gt;Bar: /* Opbygning af opstillinger på Breadboard */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Et Breadboard (også kaldet fumlebræt) er designet til at opbygge simple kredsløb uden at lodde.&lt;br /&gt;
&lt;br /&gt;
Det oprindelige udtryk stammer fra den tidlige elektronik-tid, hvor man lavede simple kredsløb ved at slå søm i et skærebræt, og lodde komponenterne på sømhovederne.&lt;br /&gt;
&lt;br /&gt;
Det nuværende breadboard er noget simplere at anvende, da man blot kan stikke komponentbenene ned i hullerne, hvor der så er et net af forbindelser.&lt;br /&gt;
&lt;br /&gt;
Der findes forskellige størrelser, men et meget anvendt format et følgende:&lt;br /&gt;
&lt;br /&gt;
[[Fil:Breadboard_Udseende.png|400px|Udseende af typisk Breadboard med 2 x 30 rækker]]&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Udseende af typisk Breadboard med 2 x 30 rækker&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Forbindelserne i et Breadboard==&lt;br /&gt;
Nede i Breadboardet får komponenterne forbindelse med nogle metalskinner, der forbinder hullerne i en bestemt struktur.&lt;br /&gt;
&lt;br /&gt;
Der er typisk en eller to baner på hver side, som har forbindelse hele vejen hen gennem breadboardet. De er ofte markeret med + og -.&lt;br /&gt;
&lt;br /&gt;
Inde omkring midten ligger der forbindelser den modsatte vej, som går ud fra midten af breadboardet. &lt;br /&gt;
&lt;br /&gt;
Dette er illustreret herunder.&lt;br /&gt;
&lt;br /&gt;
[[Fil:Breadboard_Forbindelser.png|400px|Forbindelserne i et typisk Breadboard markeret med sorte streger]]&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Forbindelserne i et typisk Breadboard markeret med sorte streger&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
En anden type breadboard er fotograferet herunder.&lt;br /&gt;
&lt;br /&gt;
[[Fil:Breadboard_Foto.png|400px|Foto af en anden type Breadboard]]&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Foto af en anden type Breadboard&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For at vise hvordan forbindelserne er lavet, er der herunder vist et billede fra undersiden af breadboardet, hvor beskyttelsen er delvist pillet af.&lt;br /&gt;
&lt;br /&gt;
[[Fil:Breadboard_Bagside.png|400px|Det ovenstående Breadboard fotograferet fra bunden, med beskyttelsen fjernet]]&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Det ovenstående Breadboard fotograferet fra bunden, med beskyttelsen fjernet&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Opbygning af opstillinger på Breadboard==&lt;br /&gt;
&lt;br /&gt;
Layoutet af Breadboardet er lavet ud fra at IC&#039;er kan monteres i midten af breadboardet, så man får mange muligheder for forbindelser &lt;br /&gt;
&lt;br /&gt;
[[Fil:Breadboard_IC.png|150px|Placeringen af en IC i en del af et breadboard]]&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Placeringen af en IC i en del af et breadboard&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Herunder er vist hvordan man kan koble en opstilling op på et breadboard. Opstillingen er tegnet i [https://www.tinkercad.com/ www.TinkerCad.com], der i skrivende stund er et gratis værktøj fra Autodesk. Der ligger flere muligheder her, men dette kan tegnes inde under Circuits.&lt;br /&gt;
&lt;br /&gt;
[[Fil:Breadboard_Opstilling.png|800px|En opstilling på breadboard koblet sammen med en Arduino UNO]]&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;En opstilling på breadboard koblet sammen med en Arduino UNO&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Kredsløbet der er bygget på breadboard er en simpel transistor, der driver en lysdiode, som vist på diagrammet herunder.&lt;br /&gt;
&lt;br /&gt;
[[Fil:Breadboard_Diagram.png|800px|Diagram over ovenstående opstilling på breadboard]]&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Diagram over ovenstående opstilling på breadboard&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Komponenter der typisk anvendes sammen med Breadboard==&lt;br /&gt;
&lt;br /&gt;
Breadboards kan naturligvis anvendes generelt, men de bliver meget brugt sammen med [[Arduino_Hardware#Breadboard|Arduino Hardware]], hvor der også omtales nogle af de andre ting, det er en fordel at have for at komme i gang.&lt;br /&gt;
&lt;br /&gt;
{{Elektronik-Montage}}&lt;br /&gt;
&lt;br /&gt;
[[Kategori:Elektronik_Montage]]&lt;/div&gt;</summary>
		<author><name>Bar</name></author>
	</entry>
	<entry>
		<id>https://www.htxarduino.dk/index.php?title=Breadboard&amp;diff=5422</id>
		<title>Breadboard</title>
		<link rel="alternate" type="text/html" href="https://www.htxarduino.dk/index.php?title=Breadboard&amp;diff=5422"/>
		<updated>2025-12-26T10:22:34Z</updated>

		<summary type="html">&lt;p&gt;Bar: /* Opbygning af opstillinger på Breadboard */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Et Breadboard (også kaldet fumlebræt) er designet til at opbygge simple kredsløb uden at lodde.&lt;br /&gt;
&lt;br /&gt;
Det oprindelige udtryk stammer fra den tidlige elektronik-tid, hvor man lavede simple kredsløb ved at slå søm i et skærebræt, og lodde komponenterne på sømhovederne.&lt;br /&gt;
&lt;br /&gt;
Det nuværende breadboard er noget simplere at anvende, da man blot kan stikke komponentbenene ned i hullerne, hvor der så er et net af forbindelser.&lt;br /&gt;
&lt;br /&gt;
Der findes forskellige størrelser, men et meget anvendt format et følgende:&lt;br /&gt;
&lt;br /&gt;
[[Fil:Breadboard_Udseende.png|400px|Udseende af typisk Breadboard med 2 x 30 rækker]]&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Udseende af typisk Breadboard med 2 x 30 rækker&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Forbindelserne i et Breadboard==&lt;br /&gt;
Nede i Breadboardet får komponenterne forbindelse med nogle metalskinner, der forbinder hullerne i en bestemt struktur.&lt;br /&gt;
&lt;br /&gt;
Der er typisk en eller to baner på hver side, som har forbindelse hele vejen hen gennem breadboardet. De er ofte markeret med + og -.&lt;br /&gt;
&lt;br /&gt;
Inde omkring midten ligger der forbindelser den modsatte vej, som går ud fra midten af breadboardet. &lt;br /&gt;
&lt;br /&gt;
Dette er illustreret herunder.&lt;br /&gt;
&lt;br /&gt;
[[Fil:Breadboard_Forbindelser.png|400px|Forbindelserne i et typisk Breadboard markeret med sorte streger]]&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Forbindelserne i et typisk Breadboard markeret med sorte streger&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
En anden type breadboard er fotograferet herunder.&lt;br /&gt;
&lt;br /&gt;
[[Fil:Breadboard_Foto.png|400px|Foto af en anden type Breadboard]]&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Foto af en anden type Breadboard&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
For at vise hvordan forbindelserne er lavet, er der herunder vist et billede fra undersiden af breadboardet, hvor beskyttelsen er delvist pillet af.&lt;br /&gt;
&lt;br /&gt;
[[Fil:Breadboard_Bagside.png|400px|Det ovenstående Breadboard fotograferet fra bunden, med beskyttelsen fjernet]]&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Det ovenstående Breadboard fotograferet fra bunden, med beskyttelsen fjernet&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Opbygning af opstillinger på Breadboard==&lt;br /&gt;
&lt;br /&gt;
Layoutet af Breadboardet er lavet ud fra at IC&#039;er kan monteres i midten af breadboardet, så man får mange muligheder for forbindelser &lt;br /&gt;
&lt;br /&gt;
[[Fil:Breadboard_IC.png|150px|Placeringen af en IC i en del af et breadboard]]&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Placeringen af en IC i en del af et breadboard&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Herunder er vist hvordan man kan koble en opstilling op på et breadboard. Opstillingen er tegnet i [https://www.tinkercad.com/ www.TinkerCad.com], der i skrivende stund er et gratis værktøj fra Autodesk. Der ligger flere muligheder her, men dette kan tegnes inde under Circuits.&lt;br /&gt;
&lt;br /&gt;
[[Fil:Breadboard_Opstilling.png|800px|En opstilling på breadboard koblet sammen med en Arduino UNO]]&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;En opstilling på breadboard koblet sammen med en Arduino UNO&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Kredsløbet der er bygget på breadboard er en simpel transistor, der driver en lysdiode, som vist på diagrammet herunder.&lt;br /&gt;
&lt;br /&gt;
[[Fil:Breadboard_Diagram.png|Diagram over ovenstående opstilling på breadboard]]&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Diagram over ovenstående opstilling på breadboard&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
==Komponenter der typisk anvendes sammen med Breadboard==&lt;br /&gt;
&lt;br /&gt;
Breadboards kan naturligvis anvendes generelt, men de bliver meget brugt sammen med [[Arduino_Hardware#Breadboard|Arduino Hardware]], hvor der også omtales nogle af de andre ting, det er en fordel at have for at komme i gang.&lt;br /&gt;
&lt;br /&gt;
{{Elektronik-Montage}}&lt;br /&gt;
&lt;br /&gt;
[[Kategori:Elektronik_Montage]]&lt;/div&gt;</summary>
		<author><name>Bar</name></author>
	</entry>
	<entry>
		<id>https://www.htxarduino.dk/index.php?title=Arduinos_Biblioteker&amp;diff=5421</id>
		<title>Arduinos Biblioteker</title>
		<link rel="alternate" type="text/html" href="https://www.htxarduino.dk/index.php?title=Arduinos_Biblioteker&amp;diff=5421"/>
		<updated>2024-09-03T07:00:24Z</updated>

		<summary type="html">&lt;p&gt;Bar: /* Steder at finde biblioteker */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Denne beskrivelse er lavet ud fra Arduinos beskrivelse af biblioteker&amp;lt;ref name=&amp;quot;libraries&amp;quot;&amp;gt;[https://www.arduino.cc/en/Hacking/Libraries Arduino Libraries - Beskrivelse af hvordan man arbejder generelt med biblioteker]&amp;lt;/ref&amp;gt; på deres egen side.&lt;br /&gt;
&lt;br /&gt;
==Standard biblioteker==&lt;br /&gt;
Det er en fordel IKKE at pille ved standard bibliotekerne.&lt;br /&gt;
&lt;br /&gt;
Som standard ligger der en del biblioteker installeret sammen med Arduinos PC program som standard indstillinger. &lt;br /&gt;
&lt;br /&gt;
[[Fil:arduino_library_structure.png|thumb|right|Biblioteks-strukturen for Arduino]]&lt;br /&gt;
==Tilføjelse af biblioteker==&lt;br /&gt;
Man kan tilføje biblioteker (testet i version 1.6.4) ved at gå ind i &amp;quot;Sketch - Include Library - Manage Libraries...&amp;quot;, hvor man kan finde en del biblioteker, som downloades fra nettet, eller hvis man har en zip-fil med et bibliotek, så kan man gå ind i &amp;quot;Sketch - Include Library - Add .ZIP Library...&amp;quot; - i begge tilfælde placeres biblioteket inde i den korrekte struktur og kan anvendes direkte.&lt;br /&gt;
&lt;br /&gt;
Hvert bibliotek ligger i sin egen mappe, og navnet på biblioteket skal være det samme som den mappe det ligger inde i, og den mappestruktur der er inde i biblioteket angiver.&lt;br /&gt;
&lt;br /&gt;
Som det er angivet på figuren her til højre, så ligger de biblioteker man selv ønsker at tilføje inde i &#039;&#039;&#039;Dokumenter\Arduino\libraries\&#039;&#039;&#039;, hvor der i dette eksempel kun er tilføjet et Keypad bibliotek.&lt;br /&gt;
&lt;br /&gt;
Et bibliotek vil normalt være skrevet i C eller C++ og vil kunne lette tilgangen til et stykke hardware som et display eller et tastatur.&lt;br /&gt;
&lt;br /&gt;
===Anvendelse af biblioteker===&lt;br /&gt;
Det letteste måde at anvende et bibliotek på er at man i IDE&#039;et går ind i &amp;quot;Sketch&amp;quot; - &amp;quot;Library&amp;quot; og vælger det bibliotek man ønsker at tilføje. Dette vil give en linje som vist her:&lt;br /&gt;
&lt;br /&gt;
 #include &amp;lt;Keypad.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Til mange biblioteker er det ikke altid nok for at forstå hvordan man anvender bibilioteket, her vil de fleste biblioteker komme med et eller flere eksempler.&lt;br /&gt;
&lt;br /&gt;
Har man lagt biblioteket rigtigt ind, så vil man kunne finde eksemplerne inde under &amp;quot;Fil&amp;quot; - &amp;quot;Eksempler&amp;quot; - &amp;quot;det relevante bibliotek&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
===Uautorisert måde at lægge biblioteker ind på===&lt;br /&gt;
Hvis man har administratorrettigheder, så kan man tilføje biblioteker inde sammen med standard bibliotekerne. Denne metode anbefales ikke.&lt;br /&gt;
&lt;br /&gt;
==Steder at finde biblioteker==&lt;br /&gt;
Der er mange biblioteker &amp;lt;ref&amp;gt;http://playground.arduino.cc/Main/LibraryList Liste over de forskellige biblioteker man kan hente fra Arduinos hjemmeside&amp;lt;/ref&amp;gt; på Arduinos hjemmeside.&lt;br /&gt;
&lt;br /&gt;
Et andet sted hvor der ligger rigtigt meget er på github.com&amp;lt;ref&amp;gt;[https://github.com/ site til samarbejde omkring software]&amp;lt;/ref&amp;gt;. Det kan være svært at navigere i stedet for at finde frem til relevante biblioteker, men man kan tit google sig frem til gode resultater ved at tilføje &amp;quot;github arduino library&amp;quot; til sin søgning efter noget hardware man ikke har kunnet finde på Arduinos side&lt;br /&gt;
&lt;br /&gt;
==At skrive sine biblioteker selv==&lt;br /&gt;
Man kan også selv skrive og udvikle biblioteker&amp;lt;ref name=&amp;quot;writeLib&amp;quot;&amp;gt;http://playground.arduino.cc/Code/Library Beskrivelse af hvordan biblioteker skal skrives&amp;lt;/ref&amp;gt;, og hvis man syntes man har skrevet et godt bibliotek kan man også poste det f.x. i Arduinos forum&amp;lt;ref&amp;gt;[http://forum.arduino.cc/ Arduinos forum]&amp;lt;/ref&amp;gt; så andre får glæde af arbejdet.&lt;br /&gt;
&lt;br /&gt;
Hvis man ønsker at skrive et bibliotek, så er det en god ide at kende strukturen i hvordan man skriver et bibliotek, da man skal skrive C++ kode, og man skal regne syntaksen i class-definitionen ud, som i sin grundlæggende struktur bliver beskrevet på Arduinos side&amp;lt;ref name=&amp;quot;writeLib&amp;quot;&amp;gt;&amp;lt;/ref&amp;gt;. Eksemplet her er dog meget simpelt, så hvis man vil ud i noget der er mere avanceret, så er det en god ide at kigge i andre lidt større eksempler, gerne fra Arduinos egen hjemmeside.&lt;br /&gt;
&lt;br /&gt;
Som vist herunder, så indeholder et bibliotek flere elementer, og det kan gøres mere eller mindre avanceret. Her vises et eksempel på Keypad-biblioteket:&amp;lt;br /&amp;gt;&lt;br /&gt;
[[fil:keypad_library.png|Oversigt over Keypad biblioteket]]&amp;lt;br /&amp;gt;&#039;&#039;Oversigt over Keypad biblioteket&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Der er en del ting der er værd at bemærke:&lt;br /&gt;
*keypad mappen ligger i mappen libraries&lt;br /&gt;
*De to filer keypad.cpp (C++ filen) og keypad.h (include-filen) skal hedde det samme som mappen&lt;br /&gt;
*keywords.txt indeholder de ord der skal syntaksfarves når man anvender biblioteket&lt;br /&gt;
*mappen examples indeholder som man kan se 7 forskellige eksempler på hvordan keypad kan bruges&lt;br /&gt;
*i dette eksempel er der mappen utility, som indeholder en class-fil der anvendes inde i keypad&lt;br /&gt;
&lt;br /&gt;
Ens eget bibliotek behøves ikke være så omfattende, men som minimum et eksempel der viser bruget af biblioteket, og som er skrevet så man kan se strukturen i hvordan man anvender biblioteket.&lt;br /&gt;
&lt;br /&gt;
===Ekstern hjælp til at skrive biblioteker===&lt;br /&gt;
På Arduinos hjemmeside er der skrevet forskellig hjælp til at oprette sine egne biblioteker.&lt;br /&gt;
&lt;br /&gt;
Selve indholdet i biblioteket er forklaret på Library Tutorial&amp;lt;ref&amp;gt;[https://www.arduino.cc/en/Hacking/libraryTutorial Library Tutorial]&amp;lt;/ref&amp;gt;. Forklaringen har ikke så meget fokus på strukturen i biblioteket, og man skal læse siden godt igennem, for at kunne se hvor de forskellige dele skal placeres i de forskellige filer.&lt;br /&gt;
&lt;br /&gt;
For at få styr på hvordan koden fordeles i de forskellige filer kan det være lettest at kigge på et eksempel, hvor der på Arduino Libraries&amp;lt;ref name=&amp;quot;libraries&amp;quot;&amp;gt;&amp;lt;/ref&amp;gt; er lavet et test eksempel nederst på siden, som illustrerer strukturen, men ikke har nogen egentlig funktion.&lt;br /&gt;
&lt;br /&gt;
Hvis man vil dele sit bibliotek med andre er gitHub.com et godt sted. For at optræde fornuftigt på gitHub er det en god ide at sikre sig at biblioteket både fungerer ordentligt og er veldokumenteret - se hvordan forskellige andre gør det. Når man har et bibliotek som er værd at dele, så kan man få hjælp til at uploade ved gitHub&amp;lt;ref&amp;gt;[https://github.com/firstcontributions/first-contributions Beskrivelse af hvordan man lægger sit første bidrag op]&amp;lt;/ref&amp;gt; eller en anden guide&amp;lt;ref&amp;gt;[https://akrabat.com/the-beginners-guide-to-contributing-to-a-github-project/ akrabat.com guide to gitHub]&amp;lt;/ref&amp;gt;. Man kan også kigge på andre måder at dele softwaren på ud fra beskrivelsen på Arduinos playground&amp;lt;ref&amp;gt;[https://playground.arduino.cc/Code/Library/#Sharing Forskellige deling af biblioteker]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
==Referencer==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Arduino-Modul-Oversigt}}&lt;br /&gt;
&lt;br /&gt;
[[Kategori:Arduino]]&lt;/div&gt;</summary>
		<author><name>Bar</name></author>
	</entry>
	<entry>
		<id>https://www.htxarduino.dk/index.php?title=Prog_Shield_LED_Strip&amp;diff=5420</id>
		<title>Prog Shield LED Strip</title>
		<link rel="alternate" type="text/html" href="https://www.htxarduino.dk/index.php?title=Prog_Shield_LED_Strip&amp;diff=5420"/>
		<updated>2024-09-02T18:29:12Z</updated>

		<summary type="html">&lt;p&gt;Bar: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[fil:WS2812_LED-Strip.jpg|thumb|right|SW2812 LED Strip]]&lt;br /&gt;
&lt;br /&gt;
WS2812 LED Strip er en række med RGB LED&#039;er, der kan styres af en enkelt digital pin. Antallet af LED&#039;er er begrænset af hvor meget strøm der kan leveres af Arduinoen.&lt;br /&gt;
&lt;br /&gt;
Den viste strip har 18 LED&#039;er og den den anvendte til eksemplet. Den er koblet op med en modstand (330-680 ohm), der fungerer som beskyttelse af både Arduino og LED-Strip ved fejltilslutning.&lt;br /&gt;
==Software==&lt;br /&gt;
Softwaren er baseret på et bibliotek lavet af Daniel Garcia&amp;lt;ref&amp;gt;[https://www.arduino.cc/reference/en/libraries/fastled/ LED-Strip library udviklet af Daniel Garcia] placeret ved GitHub&amp;lt;/ref&amp;gt;, og kan downloades som en ZIP-fil fra [https://downloads.arduino.cc/libraries/github.com/FastLED/FastLED-3.7.4.zip Denne ZIP-fil]. Biblioteket downloades og installeres som beskrevet under [[Arduinos_Biblioteker#Tilføjelse_af_biblioteker|Arduinos biblioteker]].&lt;br /&gt;
&lt;br /&gt;
===Anvendelsen af softwaren===&lt;br /&gt;
Som alle andre biblioteker skal der sættes de grundlæggende ting op for at kontakte biblioteket og definere fugtsensoren, med ben og type osv.&lt;br /&gt;
&amp;lt;SyntaxHighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
// Bibliotek, der kan styre forskellige typer LED-strips, her iblandt WS2812&lt;br /&gt;
#include &amp;lt;FastLED.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define LED_STRIP1   2  // LED strip på pin 2&lt;br /&gt;
#define NUM_LEDS    18  // Antal LED på strip&lt;br /&gt;
&lt;br /&gt;
CRGB leds1[NUM_LEDS];   // Array med farveangivelse til hver LED&lt;br /&gt;
&amp;lt;/SyntaxHighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Til programmet anvendes enkelte variabler til styring af tid og farver:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;SyntaxHighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int delayval = 100; // timing delay in milliseconds&lt;br /&gt;
&lt;br /&gt;
int i;         // Tæller-variabel til at indeksere med&lt;br /&gt;
byte R = 0;    // Mængde af Rød&lt;br /&gt;
byte G = 255;  // Mængde af Grøn&lt;br /&gt;
byte B = 0;    // Mængde af Blå&lt;br /&gt;
&amp;lt;/SyntaxHighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Inde i [[setup()]] skrives en velkomst og der skal sættes gang i objektet ved hjælp af begin-metoden som vist her:&lt;br /&gt;
&amp;lt;SyntaxHighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(9600);&lt;br /&gt;
  delay(200);&lt;br /&gt;
  Serial.println(&amp;quot;Demo af LED-Strip WS2812&amp;quot;);&lt;br /&gt;
  // Opsætning af type, benforbindelse og data&lt;br /&gt;
  FastLED.addLeds&amp;lt;WS2812, LED_STRIP1, GRB&amp;gt;(leds1, NUM_LEDS);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/SyntaxHighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I [[loop()]] genneløbes en forløkke med alle LED&#039;er, hvor farven sættes og vises, og efter et delay slukkes det igen:&lt;br /&gt;
&amp;lt;SyntaxHighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
void loop() {&lt;br /&gt;
  for (i = 0; i &amp;lt; NUM_LEDS; i++){  // Løb alle LED igennem&lt;br /&gt;
    leds1[i] = CRGB(R, G, B);      // Sæt farven på den aktuelle LED&lt;br /&gt;
    FastLED.show(0);              // Vis alle dioder - parameter 50 er intensitet for alle (0-255)&lt;br /&gt;
    delay(200);                    // Vent 200 ms&lt;br /&gt;
    leds1[i] = CRGB(0, 0, 0);      // Sluk den aktuelle LED igen&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/SyntaxHighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Koden laver et løbelys hen ad LED-Strippen, der gentages i det uendelige.&lt;br /&gt;
&lt;br /&gt;
===Anvendelse af millis() i softwaren===&lt;br /&gt;
Koden i det viste eksempel anvender [[delay()]], hvilket gør at koden er blokeret det meste af tiden. Hvis man vil uden om dette, så er løsningen at anvende [[millis()]], der måler tiden på en anden måde, ved at bruge indbygget tidsmåling i Arduinoen.&lt;br /&gt;
&lt;br /&gt;
Koden laver en lidt anden funktion, men ser ud på følgende måde:&lt;br /&gt;
&amp;lt;SyntaxHighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
// Bibliotek, der kan styre forskellige typer LED-strips, her iblandt WS2812&lt;br /&gt;
#include &amp;lt;FastLED.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define LED_STRIP1 2  // LED strip på pin 3&lt;br /&gt;
#define NUM_LEDS 18   // Antal LED på strip&lt;br /&gt;
&lt;br /&gt;
CRGB leds1[NUM_LEDS];  // Array med farveangivelse til hver LED&lt;br /&gt;
&lt;br /&gt;
int i = 0;     // Tæller-variabel til at indeksere med&lt;br /&gt;
byte R = 255;    // Mængde af Rød (0 - 255)&lt;br /&gt;
byte G = 255;  // Mængde af Grøn (0 - 255)&lt;br /&gt;
byte B = 255;    // Mængde af Blå (0 - 255)&lt;br /&gt;
unsigned long time = 0;&lt;br /&gt;
const int interval = 200;&lt;br /&gt;
unsigned long startTime = 0;&lt;br /&gt;
unsigned long endTime = 0;&lt;br /&gt;
&lt;br /&gt;
void setup() {  // Opsætning af type, benforbindelse og data&lt;br /&gt;
  Serial.begin(9600);&lt;br /&gt;
  FastLED.addLeds&amp;lt;WS2812, LED_STRIP1, GRB&amp;gt;(leds1, NUM_LEDS);&lt;br /&gt;
  delay(200);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  if ((millis() - time) &amp;gt; interval) {  // Er det tid til næste handling&lt;br /&gt;
    time = time + interval;            // Sæt tiden frem til næste handling&lt;br /&gt;
    i++;                               // Tæl frem til næste LED&lt;br /&gt;
    if (i &amp;gt;= NUM_LEDS) {               // Begræns tæller til antallet af LED&lt;br /&gt;
      for (i = 0; i &amp;lt; NUM_LEDS; i++) {&lt;br /&gt;
        leds1[i] = CRGB(0, 0, 0);  // Sluk den sidste LED igen&lt;br /&gt;
      }&lt;br /&gt;
      i = 0;&lt;br /&gt;
    }&lt;br /&gt;
    leds1[i] = CRGB(R, G, B);  // Sæt farven på den aktuelle LED&lt;br /&gt;
    startTime = micros();&lt;br /&gt;
    FastLED.show(50);            // Vis alle dioder&lt;br /&gt;
    endTime = micros();&lt;br /&gt;
    if (i == 12) {&lt;br /&gt;
      Serial.println(endTime - startTime);&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/SyntaxHighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der er lavet et eksempel på kode med millis, hvor man med en knap kan stoppe og starte løbelyset på et hvilket som helst tidspunkt. Begge koder ligger i [[media:LED-Strip-kode.zip|Denne ZIP-fil]], og for at kunne anvende eksemplet med millis, så skal man have installeret ezButton biblioteket&amp;lt;ref&amp;gt;[https://www.arduino.cc/reference/en/libraries/ezbutton/ Arduinos omtale af] exButton&amp;lt;/ref&amp;gt;. Dette kan hentes fra [https://github.com/ArduinoGetStarted/button denne github side]&lt;br /&gt;
&amp;lt;SyntaxHighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;ezButton.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ezButton button(8); &lt;br /&gt;
&amp;lt;/SyntaxHighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Software baseret på et andet bibliotek==&lt;br /&gt;
Softwaren er baseret på et bibliotek lavet af AdaFruit&amp;lt;ref&amp;gt;[https://github.com/adafruit/Adafruit_NeoPixel LED-Strip library udviklet af AdaFruit] placeret ved GitHub&amp;lt;/ref&amp;gt;, og kan downloades som en ZIP-fil fra [https://github.com/adafruit/DHT-sensor-library Denne side], eller [[media:AdaFruit_NeuPixel-Master.zip|denne ZIP-fil]]. Biblioteket downloades og installeres som beskrevet under [[Arduinos_Biblioteker#Tilføjelse_af_biblioteker|Arduinos biblioteker]].&lt;br /&gt;
&lt;br /&gt;
===Anvendelsen af softwaren===&lt;br /&gt;
Som alle andre biblioteker skal der sættes de grundlæggende ting op for at kontakte biblioteket og definere fugtsensoren, med ben og type osv.&lt;br /&gt;
&amp;lt;SyntaxHighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;Adafruit_NeoPixel.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
#define PIN 2	 // input pin Neopixel is attached to&lt;br /&gt;
&lt;br /&gt;
#define NUMPIXELS      18 // number of neopixels in strip&lt;br /&gt;
&lt;br /&gt;
Adafruit_NeoPixel pixels1 = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);&lt;br /&gt;
&amp;lt;/SyntaxHighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Til programmet anvendes enkelte variabler til styring af tid og farver:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;SyntaxHighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
int delayval = 100; // timing delay in milliseconds&lt;br /&gt;
&lt;br /&gt;
byte R = 0;    // Mængde af Rød (0 - 255)&lt;br /&gt;
byte G = 255;  // Mængde af Grøn (0 - 255)&lt;br /&gt;
byte B = 0;    // Mængde af Blå (0 - 255)&lt;br /&gt;
&amp;lt;/SyntaxHighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Inde i [[setup()]] skrives en velkomst og der skal sættes gang i objektet ved hjælp af begin-metoden som vist her:&lt;br /&gt;
&amp;lt;SyntaxHighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
void setup() {&lt;br /&gt;
  Serial.begin(9600);&lt;br /&gt;
  delay(200);&lt;br /&gt;
  Serial.println(&amp;quot;Demo af LED-Strip WS2812&amp;quot;);&lt;br /&gt;
  // Initialize the NeoPixel library.&lt;br /&gt;
  pixels1.begin();&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/SyntaxHighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I [[loop()]] genneløbes en forløkke med alle LED&#039;er, hvor farven sættes og vises, og efter et delay slukkes det igen:&lt;br /&gt;
&amp;lt;SyntaxHighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
void loop() {&lt;br /&gt;
  for (int i=0; i &amp;lt; NUMPIXELS; i++) {&lt;br /&gt;
    // pixels.Color takes RGB values, from 0,0,0 up to 255,255,255&lt;br /&gt;
    pixels1.setPixelColor(i, pixels1.Color(R, G, B));&lt;br /&gt;
&lt;br /&gt;
    // This sends the updated pixel color to the hardware.&lt;br /&gt;
    pixels1.show();&lt;br /&gt;
&lt;br /&gt;
    // Delay for a period of time (in milliseconds).&lt;br /&gt;
    delay(delayval);&lt;br /&gt;
&lt;br /&gt;
    // Turn off the LED&lt;br /&gt;
    pixels1.setPixelColor(i, pixels1.Color(0, 0, 0));&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/SyntaxHighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Koden laver et løbelys hen ad LED-Strippen, der gentages i det uendelige.&lt;br /&gt;
&lt;br /&gt;
===Anvendelse af millis() i softwaren===&lt;br /&gt;
Koden i det viste eksempel anvender [[delay()]], hvilket gør at koden er blokeret det meste af tiden. Hvis man vil uden om dette, så er løsningen at anvende [[millis()]], der måler tiden på en anden måde, ved at bruge indbygget tidsmåling i Arduinoen.&lt;br /&gt;
&lt;br /&gt;
Der er lavet et eksempel på kode med millis, hvor man med en knap kan stoppe og starte løbelyset på et hvilket som helst tidspunkt. Begge koder ligger i [[media:LED-Strip-kode.zip|Denne ZIP-fil]], og for at kunne anvende eksemplet med millis, så skal man have installeret ezButton biblioteket&amp;lt;ref&amp;gt;[https://www.arduino.cc/reference/en/libraries/ezbutton/ Arduinos omtale af] exButton&amp;lt;/ref&amp;gt;. Dette kan hentes fra [https://github.com/ArduinoGetStarted/button denne github side]&lt;br /&gt;
&amp;lt;SyntaxHighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#include &amp;lt;ezButton.h&amp;gt;&lt;br /&gt;
&lt;br /&gt;
ezButton button(8); &lt;br /&gt;
&amp;lt;/SyntaxHighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Hardware==&lt;br /&gt;
LED-Strip&#039;en skal tilkobles programmerings-shieldet, så den får stel (GND) +5V forsyning og et signal, hvor der i den viste opstilling sættes en beskyttelsesmodstand i serie med signalet. LED-Strip&#039;en kan i princippet forlænges efter ønske, og man vil stadig kunne tilgå hver enkelt LED. Det ligger i protokollen for den måde der kommunikeres med WS2812.&lt;br /&gt;
&lt;br /&gt;
I det viste eksempel er der 18 LED&#039;en koblet til, og hvis man tænder alle 18 med fuld kraft på Hvidt lys (alle farver skruet op), så kan man se at USB-porten har problemer med at forsyne Arduinoen - Power-LED&#039;en bliver svagere, men den kan klare det uden at den resetter. Vil man arbejde med flere LED-Strips med mere lys i, så skal man overveje at tilføre ekstra forsyning. &#039;&#039;&#039;ADVARSEL&#039;&#039;&#039; - Hvis man sætter for høj en spænding på 5V forsyningen af Arduinoen, så kan det skade både Arduinoen OG en tilsluttet PC.&lt;br /&gt;
&lt;br /&gt;
==Layout==&lt;br /&gt;
LED-Strippens placering på programmerings-shieldet kan ses her:&amp;lt;br /&amp;gt;&lt;br /&gt;
[[fil:Layout-LED-Strip.png|600px]]&amp;lt;br/&amp;gt;&lt;br /&gt;
&#039;&#039;Placering af LED-Strip på Programmerings-Shieldet - HUSK at vende den rigtigt&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
LED-Strippen placeres på pin 2, og vil på denne placering blokere for RF-Receiveren.&lt;br /&gt;
===Alternativ placering===&lt;br /&gt;
Hvis man ønsker at koble flere LED-Strips på Arduinoen, så kræver det en anden placering på programmerings-shieldet som det kan ses her:&amp;lt;br /&amp;gt;&lt;br /&gt;
[[fil:Layout-LED-Strip-Alt.png|600px]]&amp;lt;br/&amp;gt;&lt;br /&gt;
&#039;&#039;Alternative placeringer af LED-Strips på Programmerings-Shieldet - HUSK at vende dem rigtigt - Output pin nummer angivet&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Man skal igen være opmærksom på hvor meget strøm man bruger - man kan evt. skrue ned for lysstyrken i hver enkelt LED.&lt;br /&gt;
&lt;br /&gt;
Mulige ben med disse placeringer er pin 3, 8 og A5.&lt;br /&gt;
&lt;br /&gt;
Disse placeringer blokerer så for Andre moduler, fordi benene genbruges.&lt;br /&gt;
&lt;br /&gt;
==Referencer==&lt;br /&gt;
&amp;lt;references/&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{template:prog-shield}}&lt;br /&gt;
&lt;br /&gt;
[[Kategori:Programmerings-Shield]]&lt;/div&gt;</summary>
		<author><name>Bar</name></author>
	</entry>
	<entry>
		<id>https://www.htxarduino.dk/index.php?title=Rotary_Encoder&amp;diff=5419</id>
		<title>Rotary Encoder</title>
		<link rel="alternate" type="text/html" href="https://www.htxarduino.dk/index.php?title=Rotary_Encoder&amp;diff=5419"/>
		<updated>2024-05-02T09:17:30Z</updated>

		<summary type="html">&lt;p&gt;Bar: /* Kodeeksempel til Arduino */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Fil:Modul-24.jpg|thumb|right|200px|Billede af Rotary Encoder modul]]&lt;br /&gt;
&lt;br /&gt;
Rotary Encoder modulet har et skaft på toppen, som kan roteres omkring en lodret akse. Dette skaft kan roteres uendeligt. Modulet kan registrere registrere skaftets rotationer. &lt;br /&gt;
&lt;br /&gt;
Rotary encoders bliver brugt til mange processer, som kræver præcis uendelig rotation. Eksempelvis kan det bruges til computer mus med drejehjul, hvor det skal registreres i hvor meget kuglen drejer og i hvilke retninger. Det kan bruges til robotter, for at registrere hvor meget robotens motorer er drejet. Det kan også bruges i kamerar linser, for at undersøge hvor meget kameraret er zoomet ind.&lt;br /&gt;
&lt;br /&gt;
Siden at modulet kan rotere uendeligt, har den ikke rigtigt nogen start eller slutning, men hvis man, i koden, holder styr på rotationen, så kan man bruge modulet bruges til at skrue op eller ned for noget, eksempelvis volumen af lyd eller styrken af lys lys. Rotary Encoder afgiver kun information når der bliver drejet på skaftet, den kan altså ikke fortælle nuværende position. Hvis man skal have en start position, skal man sætte skaftets nuværende position til start og så vil man derefter kunne skrue op eller ned. Modulet kan dog heller ikke gemme informationer, så når programmet bliver genstartet, vil den igen gøre skaftets nuværende position til start position. Så hvis man ønsker en position, som fast skal være start position, så skal man enten, aldrig lukke programmet eller sætte skaftets position tilbage til start før man starter sit program.&lt;br /&gt;
&lt;br /&gt;
==Benforbindelser til modul==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Signal!!pin!!Pic-pin!!Forklaring&lt;br /&gt;
|-&lt;br /&gt;
|GND||1||10||Stel-forbindelse&lt;br /&gt;
|-&lt;br /&gt;
| + ||2||9||+ 5V forsyning&lt;br /&gt;
|-&lt;br /&gt;
|SW||3||5||Kontakt i Rotary Encoder, der trækker mod stel, når den trykkes ind&lt;br /&gt;
|-&lt;br /&gt;
|DT||4||4||Data signal - en del af rotations aftastning&lt;br /&gt;
|-&lt;br /&gt;
|CLK||5||3||Clock signal - en del af rotations aftastning&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Princip-diagram for Rotary Encoder==&lt;br /&gt;
{| &lt;br /&gt;
|-&lt;br /&gt;
|valign=&amp;quot;top&amp;quot;|&lt;br /&gt;
&lt;br /&gt;
Selve rotary encoderen er vist som de to switche U$1 og U$2, hvor der sidder to pull-up modstande R2 og R3 der er monteret på printet.&lt;br /&gt;
&lt;br /&gt;
Den sidste del er trykknappen S1, der sidder i drejeakslen, der kan aktiveres ved at trykke akslen indad.&lt;br /&gt;
På printet er der plads til en pull up, men den er ikke monteret, så den kan man eftermontere (SMD), eller man kan placere den uden for printet.&lt;br /&gt;
&lt;br /&gt;
|valign=&amp;quot;top&amp;quot;|&lt;br /&gt;
[[Image:Rotary_diagram.PNG|400px|Principskitse af Rotary Encoder]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Forklaring til aflæsning af Rotary Encoder===&lt;br /&gt;
Når man drejer på Rotary Encoderen, så giver den to faseforskudte signaler ud, som vist her:&lt;br /&gt;
&lt;br /&gt;
[[Image:Rotary_full_count.PNG|Tidsdiagram for Rotary Encoder med tælleskridt]]&lt;br /&gt;
&lt;br /&gt;
Som det kan ses på tallene under kurverne, så tæller man et skridt hver gang der kommer en kant i signalerne fra enten CLK eller Data. Når Data er faseforskudt så den kommer efter CLK, så tælles der opad, og når faseforskydningen vender, så Data kommer før CLK, så tælles der nedad.&lt;br /&gt;
&lt;br /&gt;
Mellem hvert &amp;quot;klik&amp;quot; på rotary encoderen tælles enten 4 gange op eller 4 gange ned.&lt;br /&gt;
&lt;br /&gt;
Det kan man anvendelsesmæssigt håndtere ved at dividere tallet med 4.&lt;br /&gt;
&lt;br /&gt;
Man kan også tælle lidt simplere, så man kun ændrer noget, hver gang CLK går fra lav til høj, som det er illustreret her:&lt;br /&gt;
&lt;br /&gt;
[[Image:Rotary_single_count.PNG|Tidsdiagram for Rotary Encoder med enkelt tælling]]&lt;br /&gt;
&lt;br /&gt;
Som det kan ses tælles der ved de positivt gående kanter på CLK, og der tælles op når Data er høj, og ned når Data er lav. &lt;br /&gt;
&lt;br /&gt;
Dette princip virke umiddelbart enkelt, men det kan også have en ulempe, nemlig at der kan tælles forkert, hvis CLK giver flere positive kanter, men Data står på samme niveau, som det er illustreret her:&lt;br /&gt;
&lt;br /&gt;
[[Image:Rotary_single_fejl.PNG|Tidsdiagram for Rotary Encoder med fejltælling]]&lt;br /&gt;
&lt;br /&gt;
==Software modulet Rotary.jal==&lt;br /&gt;
Der ligger en servicerutine i Rotary modulet, hvor man kan få at vide om der er kommet en ny værdi, og den værdi kan aflæses i variablen Rotary_value, der er et signed word, som altså kan antage værdier fra -32768 til 32767.&lt;br /&gt;
&lt;br /&gt;
Ved opstart står Rotary_value på 0.&lt;br /&gt;
&lt;br /&gt;
Modulet kan anvende 4 forskellige principper.&lt;br /&gt;
&lt;br /&gt;
Man kan vælge at arbejde med alle tælleskridt, så der kommer 80 på en omgang, men 4 trin for hvert &amp;quot;klik&amp;quot; på encoderen, eller man kan vælge at aflæse så der kommer 20 på en omgang, men med muligheden for at der opstår fejl.&lt;br /&gt;
&lt;br /&gt;
Man kan også vælge om man vil servicere ved blot at kalde tit nok, eller om man vil lade en interrupt-rutine håndtere aflæsningen. Begge metoder kan kombineres frit uden begrænsninger.&lt;br /&gt;
&lt;br /&gt;
===Anvendelse af Rotary Encoder===&lt;br /&gt;
Når man vil anvende Rotary Encoder modulet, så skal man [[include]] Rotary.jal som følger:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;jal&amp;quot;&amp;gt;&lt;br /&gt;
   include Rotary.jal&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hvis Rotary.jal ligger i \lib inde i c:\jalpack så kan compileren finde modulet.&lt;br /&gt;
&lt;br /&gt;
[[JAL-fil]]en ligger sammen med et par eksempler inde i [[media:Rotary_jal.zip|en samlet ZIP-fil]]&lt;br /&gt;
&lt;br /&gt;
Rotary er testet på følgende kombinationer:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!PIC!!pin&lt;br /&gt;
|-&lt;br /&gt;
|[[PIC16F684]]||CLK=a2 DT=a3&lt;br /&gt;
|-&lt;br /&gt;
|[[PIC16F690]]||CLK=a2 DT=a3 - med alle kombinationer af interrupt og fuld/enkelt tælling&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Interface fil til Rotary Encoder===&lt;br /&gt;
Man kan indstille de beskrevne ting i interfacefilen, samt man kan vælge hvilke indgange man ønsker at anvende til at aflæse encoderen med.&lt;br /&gt;
&lt;br /&gt;
I Rotary_def.jal kan antallet af tælleskridt indstilles ved:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;jal&amp;quot;&amp;gt;&lt;br /&gt;
Const rotary_single = false&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
False giver 4 skridt pr. klik og true giver 1 skridt pr. klik (kan lave fejl).&lt;br /&gt;
&lt;br /&gt;
I Rotary_def.jal kan der indstilles om man skal bruge interrupt ved:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;jal&amp;quot;&amp;gt;&lt;br /&gt;
Const rotary_interrupt = true&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Placeringen af benene er lidt mere kompliceret, specielt på [[PIC16F690]], hvor man både kan bruge ben i PORTA og PORTB til det - dog med den begrænsning at man skal bruge to ben i samme port.&amp;lt;br /&amp;gt;&lt;br /&gt;
Man angiver hvilken port det er  med følgende angivelse:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;jal&amp;quot;&amp;gt;&lt;br /&gt;
alias     Rotary_port                is porta&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Som normalt skal man angive hvilke pins det er ved navnene. Her skal navngives CLK og Data, samt direction-benene for de samme:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;jal&amp;quot;&amp;gt;&lt;br /&gt;
alias     Rotary_pin_clk             is pin_A2      -- clock pin&lt;br /&gt;
alias     Rotary_pin_dt              is pin_A3      -- data pin.&lt;br /&gt;
--&lt;br /&gt;
alias     Rotary_pin_direction_clk   is pin_A2_direction&lt;br /&gt;
alias     Rotary_pin_direction_dt    is pin_A3_direction&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Til indstilling af interruptet skal man angive hvilke interrupt-indstillinger det er:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;jal&amp;quot;&amp;gt;&lt;br /&gt;
alias     Rotary_int_clk             is IOCA_IOCA2&lt;br /&gt;
alias     Rotary_int_dt              is IOCA_IOCA3&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Endelig skal der kunne angives hvilke bit det er i de spejlede variabler inde i rutinerne, og det gøres blot ved at angive bit-nummeret som vist her:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;jal&amp;quot;&amp;gt;&lt;br /&gt;
const     Rotary_clk_bit             = 2&lt;br /&gt;
const     Rotary_dt_bit              = 3&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Anvendelsen af Rotary Encoder==&lt;br /&gt;
&lt;br /&gt;
Man skal foretage valgene omkring interrupt ud fra om man lave sin kode så modulet serviceres meget ofte, og om man skal have visning på alle nye værdier, samt om man må miste værdier (om man har et fast nul-punkt).&lt;br /&gt;
&lt;br /&gt;
Så skal man vælge om man vil have alle tælleskridt med, eller om man vil have 1 tælleskridt pr. klik, med den ulempe, at man kan få falske tællinger.&lt;br /&gt;
&lt;br /&gt;
Ud over det er anvendelsen ret simpel:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;jal&amp;quot;&amp;gt;&lt;br /&gt;
 include Rorary.jal&lt;br /&gt;
&lt;br /&gt;
 forever loop&lt;br /&gt;
   if new_rotary_value then&lt;br /&gt;
      rotary_value  -- anvend den nye værdi til noget fornuftigt&lt;br /&gt;
   end if&lt;br /&gt;
   --&lt;br /&gt;
   -- Her kan placeres anden kode i loopet, der skal lave andre ting&lt;br /&gt;
   --&lt;br /&gt;
 end loop&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Forklaring af Rotary software==&lt;br /&gt;
&lt;br /&gt;
Her forklares i detaljer hvordan modulet fungerer inde i software-modulet&lt;br /&gt;
&lt;br /&gt;
===Initialisering af softwaren===&lt;br /&gt;
&lt;br /&gt;
Initialiseringen kan i [[Pseudokode]] udtrykkes som følger:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   Læs opsætningen i Rotary_def.jal&lt;br /&gt;
   Sæt Rotary_value til 0&lt;br /&gt;
   indstil interruptet, hvis det skal anvendes&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Funktionen new_rotary_value===&lt;br /&gt;
&lt;br /&gt;
Funktionen kaldes ofte, og når der er en ny værdi, så returnerer den true, og man kan aflæse status på tælleren i rotary_value.&lt;br /&gt;
&lt;br /&gt;
Hvis man ikke anvender interrupt, så skal funktionen kaldes så ofte, at man ikke mister tælleskridt. Anvender man interruptet, så vil der blot ligge den værdi man er kommet til.&lt;br /&gt;
&lt;br /&gt;
===Konstanterne i interface-filen===&lt;br /&gt;
Det er mest af alt de indstillinger der er beskrevet tidligere.&lt;br /&gt;
&lt;br /&gt;
===Funktionsbeskrivelse===&lt;br /&gt;
&lt;br /&gt;
Princippet for at registrere tælling af enkelt skridt kan i [[pseudokode]] udtrykkes som følger:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Hvis der er en forkant på CLK så&lt;br /&gt;
   Marker at der er sket en ændring&lt;br /&gt;
   Hvis Data er høj så&lt;br /&gt;
      Tæl en op&lt;br /&gt;
   ellers&lt;br /&gt;
      Tæl en ned&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dette kan ske direkte i servicerutinen, eller hvis det er med interrupt, så sker det ved at registreringen sker i interruptet, og servicerutinen registrerer at det er sket.&lt;br /&gt;
&lt;br /&gt;
På samme måde laves tællingen på alle kanter enten i interruptet eller i servicerutinen.&amp;lt;br /&amp;gt;&lt;br /&gt;
Som pseudokode er det lidt mere kompliceret:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Hvis der er sket et skift på CLK så&lt;br /&gt;
   Marker at der er sket en ændring&lt;br /&gt;
   Hvis CLK er Høj så&lt;br /&gt;
      Hvis Data er høj så&lt;br /&gt;
         Tæl en op&lt;br /&gt;
      Ellers&lt;br /&gt;
         Tæl en ned&lt;br /&gt;
   Ellers&lt;br /&gt;
      Hvis Data er høj så&lt;br /&gt;
         Tæl en ned&lt;br /&gt;
      Ellers&lt;br /&gt;
         Tæl en op&lt;br /&gt;
Ellers&lt;br /&gt;
   Hvis der er sket et skift på Data så&lt;br /&gt;
      Marker at der er sket en ændring&lt;br /&gt;
      Hvis Data er Høj så&lt;br /&gt;
         Hvis CLK er høj så&lt;br /&gt;
            Tæl en ned&lt;br /&gt;
         Ellers&lt;br /&gt;
            Tæl en op&lt;br /&gt;
      Ellers&lt;br /&gt;
         Hvis CLK er høj så&lt;br /&gt;
            Tæl en op&lt;br /&gt;
         Ellers&lt;br /&gt;
            Tæl en ned&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Koden inde i funktionerne===&lt;br /&gt;
&lt;br /&gt;
Koden er ret uoverskuelig, specielt fordi den skal kunne fungere på 4 forskellige måder, ud fra de indstillinger der er lavet i interface-filen.&lt;br /&gt;
&lt;br /&gt;
Det er også således at noget løses i interrupt, mens andet løses i servicerutinen.&lt;br /&gt;
&lt;br /&gt;
Koden ligger sammen med eksempler og en demo inde i [[media:Rotary_jal.zip|en samlet ZIP-fil]].&lt;br /&gt;
&lt;br /&gt;
==Kodeeksempel til Arduino==&lt;br /&gt;
Dette eksempel er givet for at vise hvordan Rotary Encoderen kan anvendes til Arduino.&lt;br /&gt;
&lt;br /&gt;
Den konkrete kode tager udgangspunkt i pseudokoden, og bliver ikke forklaret i detaljer, men der forklares de ting, der har er specielt for denne kode.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxHighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#define CLK_PIN 3&lt;br /&gt;
#define DT_PIN 4&lt;br /&gt;
&lt;br /&gt;
int countValue = 0;&lt;br /&gt;
bool lastClk;&lt;br /&gt;
bool lastDt;&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  pinMode(CLK_PIN, INPUT);&lt;br /&gt;
  pinMode(DT_PIN, INPUT);&lt;br /&gt;
  Serial.begin(500000);&lt;br /&gt;
  delay(100);&lt;br /&gt;
  Serial.println(&amp;quot;\r\nRotary Switch Simple demo&amp;quot;);&lt;br /&gt;
  lastClk = digitalRead(CLK_PIN);&lt;br /&gt;
  lastDt = digitalRead(DT_PIN);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void printCount() {&lt;br /&gt;
  Serial.print(&amp;quot;Count:\t&amp;quot;);&lt;br /&gt;
  Serial.print(countValue);&lt;br /&gt;
  int countClick = countValue / 4;&lt;br /&gt;
  Serial.print(&amp;quot;\t&amp;quot;);&lt;br /&gt;
  Serial.println(countClick);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  bool clkNow = digitalRead(CLK_PIN);&lt;br /&gt;
  bool dtNow = digitalRead(DT_PIN);&lt;br /&gt;
  if (clkNow != lastClk) {&lt;br /&gt;
    if (clkNow) {&lt;br /&gt;
      if (dtNow) {&lt;br /&gt;
        countValue++;&lt;br /&gt;
      } else {&lt;br /&gt;
        countValue--;&lt;br /&gt;
      }&lt;br /&gt;
    } else {&lt;br /&gt;
      if (dtNow) {&lt;br /&gt;
        countValue--;&lt;br /&gt;
      } else {&lt;br /&gt;
        countValue++;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
    lastClk = clkNow;&lt;br /&gt;
    printCount();&lt;br /&gt;
  }&lt;br /&gt;
  if (dtNow != lastDt) {&lt;br /&gt;
    if (dtNow) {&lt;br /&gt;
      if (clkNow) {&lt;br /&gt;
        countValue--;&lt;br /&gt;
      } else {&lt;br /&gt;
        countValue++;&lt;br /&gt;
      }&lt;br /&gt;
    } else {&lt;br /&gt;
      if (clkNow) {&lt;br /&gt;
        countValue++;&lt;br /&gt;
      } else {&lt;br /&gt;
        countValue--;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
    lastDt = dtNow;&lt;br /&gt;
    printCount();&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxHighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Koden læser alle skift på de to signaler CLK og DT, og som Rotary Encoderen (den der er testet til koden) er opbygget, så for hvert klik der er i omgangen (20 klik i alt), så er der 4 skift. Når koden skriver ud i Serial monitor, så kommer der udskrift på alle kanter.&lt;br /&gt;
&lt;br /&gt;
Udskriften viser to værdier - tællingen på kanterne og så den tælling delt med 4, som modsvarer de klik der er i Rotary Encoderen.&lt;br /&gt;
Hvis man kun ønskede udskrift for hvert klik, så kunne man i funktionen printCount() tilføje en linje, så den kommer til at se ud på følgende måde:&lt;br /&gt;
&amp;lt;syntaxHighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
void printCount() {&lt;br /&gt;
  if ((countValue % 4) != 0) return;&lt;br /&gt;
  Serial.print(&amp;quot;Count:\t&amp;quot;);&lt;br /&gt;
  Serial.print(countValue);&lt;br /&gt;
  int countClick = countValue / 4;&lt;br /&gt;
  Serial.print(&amp;quot;\t&amp;quot;);&lt;br /&gt;
  Serial.println(countClick);&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxHighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I setup() sættes den serielle Baud Rate til 500000. Grunden til dette er at koden i loop() er tidsfølsom, forstået på den måde, at hvis der er noget i loop() der tager lang tid, så kan koden springe over kanter, og dermed ikke tælle rigtigt. Dette blev observeret ved en Baud Rate på 9600, hvor det der skulle skrives ud kom til at vente på at der blev skrevet ud, så signaler blev sprunget over. Måden det blev konstateret var at markere et nulpunkt, og så dreje stille og roligt fx 2 omgange. Dette gav som forventet 160 kanter. Ved så at køre hurtigt to omgange retur skulle man forvente at tallet kom tilbage på 0 - dette var ikke tilfældet, altså var der kanter der blev sprunget over.&lt;br /&gt;
&lt;br /&gt;
Med ovenstående erfaring, så skal man være meget opmærksom på tid i udvikling af software, specielt hvis Rotary Encoderen skal kunne fungere i alle situationer. Man skal passe på  med alt - specielt delay() må man bare ikke have i koden så den fungerer på tidspunkter hvor der skal kunne registreres fra Rotary Encoderen, med også display-rutiner LED-strip og mange andre ting vil kunne give problemer. Er man i tvivl vil man kunne lave en test som beskrevet ovenfor.&lt;br /&gt;
&lt;br /&gt;
Alternativt skal man skrive koden om, så den fungerer på interrupt. Dette er ikke dokumenteret her.&lt;br /&gt;
&lt;br /&gt;
{{moduler}}&lt;br /&gt;
&lt;br /&gt;
{{keyes-moduler}}&lt;br /&gt;
 &lt;br /&gt;
[[Kategori:Flere digitale signaler]]&lt;br /&gt;
[[Kategori:JAL-moduler]]&lt;/div&gt;</summary>
		<author><name>Bar</name></author>
	</entry>
	<entry>
		<id>https://www.htxarduino.dk/index.php?title=Rotary_Encoder&amp;diff=5418</id>
		<title>Rotary Encoder</title>
		<link rel="alternate" type="text/html" href="https://www.htxarduino.dk/index.php?title=Rotary_Encoder&amp;diff=5418"/>
		<updated>2024-05-02T07:07:01Z</updated>

		<summary type="html">&lt;p&gt;Bar: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Fil:Modul-24.jpg|thumb|right|200px|Billede af Rotary Encoder modul]]&lt;br /&gt;
&lt;br /&gt;
Rotary Encoder modulet har et skaft på toppen, som kan roteres omkring en lodret akse. Dette skaft kan roteres uendeligt. Modulet kan registrere registrere skaftets rotationer. &lt;br /&gt;
&lt;br /&gt;
Rotary encoders bliver brugt til mange processer, som kræver præcis uendelig rotation. Eksempelvis kan det bruges til computer mus med drejehjul, hvor det skal registreres i hvor meget kuglen drejer og i hvilke retninger. Det kan bruges til robotter, for at registrere hvor meget robotens motorer er drejet. Det kan også bruges i kamerar linser, for at undersøge hvor meget kameraret er zoomet ind.&lt;br /&gt;
&lt;br /&gt;
Siden at modulet kan rotere uendeligt, har den ikke rigtigt nogen start eller slutning, men hvis man, i koden, holder styr på rotationen, så kan man bruge modulet bruges til at skrue op eller ned for noget, eksempelvis volumen af lyd eller styrken af lys lys. Rotary Encoder afgiver kun information når der bliver drejet på skaftet, den kan altså ikke fortælle nuværende position. Hvis man skal have en start position, skal man sætte skaftets nuværende position til start og så vil man derefter kunne skrue op eller ned. Modulet kan dog heller ikke gemme informationer, så når programmet bliver genstartet, vil den igen gøre skaftets nuværende position til start position. Så hvis man ønsker en position, som fast skal være start position, så skal man enten, aldrig lukke programmet eller sætte skaftets position tilbage til start før man starter sit program.&lt;br /&gt;
&lt;br /&gt;
==Benforbindelser til modul==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Signal!!pin!!Pic-pin!!Forklaring&lt;br /&gt;
|-&lt;br /&gt;
|GND||1||10||Stel-forbindelse&lt;br /&gt;
|-&lt;br /&gt;
| + ||2||9||+ 5V forsyning&lt;br /&gt;
|-&lt;br /&gt;
|SW||3||5||Kontakt i Rotary Encoder, der trækker mod stel, når den trykkes ind&lt;br /&gt;
|-&lt;br /&gt;
|DT||4||4||Data signal - en del af rotations aftastning&lt;br /&gt;
|-&lt;br /&gt;
|CLK||5||3||Clock signal - en del af rotations aftastning&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Princip-diagram for Rotary Encoder==&lt;br /&gt;
{| &lt;br /&gt;
|-&lt;br /&gt;
|valign=&amp;quot;top&amp;quot;|&lt;br /&gt;
&lt;br /&gt;
Selve rotary encoderen er vist som de to switche U$1 og U$2, hvor der sidder to pull-up modstande R2 og R3 der er monteret på printet.&lt;br /&gt;
&lt;br /&gt;
Den sidste del er trykknappen S1, der sidder i drejeakslen, der kan aktiveres ved at trykke akslen indad.&lt;br /&gt;
På printet er der plads til en pull up, men den er ikke monteret, så den kan man eftermontere (SMD), eller man kan placere den uden for printet.&lt;br /&gt;
&lt;br /&gt;
|valign=&amp;quot;top&amp;quot;|&lt;br /&gt;
[[Image:Rotary_diagram.PNG|400px|Principskitse af Rotary Encoder]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Forklaring til aflæsning af Rotary Encoder===&lt;br /&gt;
Når man drejer på Rotary Encoderen, så giver den to faseforskudte signaler ud, som vist her:&lt;br /&gt;
&lt;br /&gt;
[[Image:Rotary_full_count.PNG|Tidsdiagram for Rotary Encoder med tælleskridt]]&lt;br /&gt;
&lt;br /&gt;
Som det kan ses på tallene under kurverne, så tæller man et skridt hver gang der kommer en kant i signalerne fra enten CLK eller Data. Når Data er faseforskudt så den kommer efter CLK, så tælles der opad, og når faseforskydningen vender, så Data kommer før CLK, så tælles der nedad.&lt;br /&gt;
&lt;br /&gt;
Mellem hvert &amp;quot;klik&amp;quot; på rotary encoderen tælles enten 4 gange op eller 4 gange ned.&lt;br /&gt;
&lt;br /&gt;
Det kan man anvendelsesmæssigt håndtere ved at dividere tallet med 4.&lt;br /&gt;
&lt;br /&gt;
Man kan også tælle lidt simplere, så man kun ændrer noget, hver gang CLK går fra lav til høj, som det er illustreret her:&lt;br /&gt;
&lt;br /&gt;
[[Image:Rotary_single_count.PNG|Tidsdiagram for Rotary Encoder med enkelt tælling]]&lt;br /&gt;
&lt;br /&gt;
Som det kan ses tælles der ved de positivt gående kanter på CLK, og der tælles op når Data er høj, og ned når Data er lav. &lt;br /&gt;
&lt;br /&gt;
Dette princip virke umiddelbart enkelt, men det kan også have en ulempe, nemlig at der kan tælles forkert, hvis CLK giver flere positive kanter, men Data står på samme niveau, som det er illustreret her:&lt;br /&gt;
&lt;br /&gt;
[[Image:Rotary_single_fejl.PNG|Tidsdiagram for Rotary Encoder med fejltælling]]&lt;br /&gt;
&lt;br /&gt;
==Software modulet Rotary.jal==&lt;br /&gt;
Der ligger en servicerutine i Rotary modulet, hvor man kan få at vide om der er kommet en ny værdi, og den værdi kan aflæses i variablen Rotary_value, der er et signed word, som altså kan antage værdier fra -32768 til 32767.&lt;br /&gt;
&lt;br /&gt;
Ved opstart står Rotary_value på 0.&lt;br /&gt;
&lt;br /&gt;
Modulet kan anvende 4 forskellige principper.&lt;br /&gt;
&lt;br /&gt;
Man kan vælge at arbejde med alle tælleskridt, så der kommer 80 på en omgang, men 4 trin for hvert &amp;quot;klik&amp;quot; på encoderen, eller man kan vælge at aflæse så der kommer 20 på en omgang, men med muligheden for at der opstår fejl.&lt;br /&gt;
&lt;br /&gt;
Man kan også vælge om man vil servicere ved blot at kalde tit nok, eller om man vil lade en interrupt-rutine håndtere aflæsningen. Begge metoder kan kombineres frit uden begrænsninger.&lt;br /&gt;
&lt;br /&gt;
===Anvendelse af Rotary Encoder===&lt;br /&gt;
Når man vil anvende Rotary Encoder modulet, så skal man [[include]] Rotary.jal som følger:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;jal&amp;quot;&amp;gt;&lt;br /&gt;
   include Rotary.jal&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hvis Rotary.jal ligger i \lib inde i c:\jalpack så kan compileren finde modulet.&lt;br /&gt;
&lt;br /&gt;
[[JAL-fil]]en ligger sammen med et par eksempler inde i [[media:Rotary_jal.zip|en samlet ZIP-fil]]&lt;br /&gt;
&lt;br /&gt;
Rotary er testet på følgende kombinationer:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!PIC!!pin&lt;br /&gt;
|-&lt;br /&gt;
|[[PIC16F684]]||CLK=a2 DT=a3&lt;br /&gt;
|-&lt;br /&gt;
|[[PIC16F690]]||CLK=a2 DT=a3 - med alle kombinationer af interrupt og fuld/enkelt tælling&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Interface fil til Rotary Encoder===&lt;br /&gt;
Man kan indstille de beskrevne ting i interfacefilen, samt man kan vælge hvilke indgange man ønsker at anvende til at aflæse encoderen med.&lt;br /&gt;
&lt;br /&gt;
I Rotary_def.jal kan antallet af tælleskridt indstilles ved:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;jal&amp;quot;&amp;gt;&lt;br /&gt;
Const rotary_single = false&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
False giver 4 skridt pr. klik og true giver 1 skridt pr. klik (kan lave fejl).&lt;br /&gt;
&lt;br /&gt;
I Rotary_def.jal kan der indstilles om man skal bruge interrupt ved:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;jal&amp;quot;&amp;gt;&lt;br /&gt;
Const rotary_interrupt = true&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Placeringen af benene er lidt mere kompliceret, specielt på [[PIC16F690]], hvor man både kan bruge ben i PORTA og PORTB til det - dog med den begrænsning at man skal bruge to ben i samme port.&amp;lt;br /&amp;gt;&lt;br /&gt;
Man angiver hvilken port det er  med følgende angivelse:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;jal&amp;quot;&amp;gt;&lt;br /&gt;
alias     Rotary_port                is porta&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Som normalt skal man angive hvilke pins det er ved navnene. Her skal navngives CLK og Data, samt direction-benene for de samme:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;jal&amp;quot;&amp;gt;&lt;br /&gt;
alias     Rotary_pin_clk             is pin_A2      -- clock pin&lt;br /&gt;
alias     Rotary_pin_dt              is pin_A3      -- data pin.&lt;br /&gt;
--&lt;br /&gt;
alias     Rotary_pin_direction_clk   is pin_A2_direction&lt;br /&gt;
alias     Rotary_pin_direction_dt    is pin_A3_direction&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Til indstilling af interruptet skal man angive hvilke interrupt-indstillinger det er:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;jal&amp;quot;&amp;gt;&lt;br /&gt;
alias     Rotary_int_clk             is IOCA_IOCA2&lt;br /&gt;
alias     Rotary_int_dt              is IOCA_IOCA3&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Endelig skal der kunne angives hvilke bit det er i de spejlede variabler inde i rutinerne, og det gøres blot ved at angive bit-nummeret som vist her:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;jal&amp;quot;&amp;gt;&lt;br /&gt;
const     Rotary_clk_bit             = 2&lt;br /&gt;
const     Rotary_dt_bit              = 3&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Anvendelsen af Rotary Encoder==&lt;br /&gt;
&lt;br /&gt;
Man skal foretage valgene omkring interrupt ud fra om man lave sin kode så modulet serviceres meget ofte, og om man skal have visning på alle nye værdier, samt om man må miste værdier (om man har et fast nul-punkt).&lt;br /&gt;
&lt;br /&gt;
Så skal man vælge om man vil have alle tælleskridt med, eller om man vil have 1 tælleskridt pr. klik, med den ulempe, at man kan få falske tællinger.&lt;br /&gt;
&lt;br /&gt;
Ud over det er anvendelsen ret simpel:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;jal&amp;quot;&amp;gt;&lt;br /&gt;
 include Rorary.jal&lt;br /&gt;
&lt;br /&gt;
 forever loop&lt;br /&gt;
   if new_rotary_value then&lt;br /&gt;
      rotary_value  -- anvend den nye værdi til noget fornuftigt&lt;br /&gt;
   end if&lt;br /&gt;
   --&lt;br /&gt;
   -- Her kan placeres anden kode i loopet, der skal lave andre ting&lt;br /&gt;
   --&lt;br /&gt;
 end loop&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Forklaring af Rotary software==&lt;br /&gt;
&lt;br /&gt;
Her forklares i detaljer hvordan modulet fungerer inde i software-modulet&lt;br /&gt;
&lt;br /&gt;
===Initialisering af softwaren===&lt;br /&gt;
&lt;br /&gt;
Initialiseringen kan i [[Pseudokode]] udtrykkes som følger:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   Læs opsætningen i Rotary_def.jal&lt;br /&gt;
   Sæt Rotary_value til 0&lt;br /&gt;
   indstil interruptet, hvis det skal anvendes&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Funktionen new_rotary_value===&lt;br /&gt;
&lt;br /&gt;
Funktionen kaldes ofte, og når der er en ny værdi, så returnerer den true, og man kan aflæse status på tælleren i rotary_value.&lt;br /&gt;
&lt;br /&gt;
Hvis man ikke anvender interrupt, så skal funktionen kaldes så ofte, at man ikke mister tælleskridt. Anvender man interruptet, så vil der blot ligge den værdi man er kommet til.&lt;br /&gt;
&lt;br /&gt;
===Konstanterne i interface-filen===&lt;br /&gt;
Det er mest af alt de indstillinger der er beskrevet tidligere.&lt;br /&gt;
&lt;br /&gt;
===Funktionsbeskrivelse===&lt;br /&gt;
&lt;br /&gt;
Princippet for at registrere tælling af enkelt skridt kan i [[pseudokode]] udtrykkes som følger:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Hvis der er en forkant på CLK så&lt;br /&gt;
   Marker at der er sket en ændring&lt;br /&gt;
   Hvis Data er høj så&lt;br /&gt;
      Tæl en op&lt;br /&gt;
   ellers&lt;br /&gt;
      Tæl en ned&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dette kan ske direkte i servicerutinen, eller hvis det er med interrupt, så sker det ved at registreringen sker i interruptet, og servicerutinen registrerer at det er sket.&lt;br /&gt;
&lt;br /&gt;
På samme måde laves tællingen på alle kanter enten i interruptet eller i servicerutinen.&amp;lt;br /&amp;gt;&lt;br /&gt;
Som pseudokode er det lidt mere kompliceret:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Hvis der er sket et skift på CLK så&lt;br /&gt;
   Marker at der er sket en ændring&lt;br /&gt;
   Hvis CLK er Høj så&lt;br /&gt;
      Hvis Data er høj så&lt;br /&gt;
         Tæl en op&lt;br /&gt;
      Ellers&lt;br /&gt;
         Tæl en ned&lt;br /&gt;
   Ellers&lt;br /&gt;
      Hvis Data er høj så&lt;br /&gt;
         Tæl en ned&lt;br /&gt;
      Ellers&lt;br /&gt;
         Tæl en op&lt;br /&gt;
Ellers&lt;br /&gt;
   Hvis der er sket et skift på Data så&lt;br /&gt;
      Marker at der er sket en ændring&lt;br /&gt;
      Hvis Data er Høj så&lt;br /&gt;
         Hvis CLK er høj så&lt;br /&gt;
            Tæl en ned&lt;br /&gt;
         Ellers&lt;br /&gt;
            Tæl en op&lt;br /&gt;
      Ellers&lt;br /&gt;
         Hvis CLK er høj så&lt;br /&gt;
            Tæl en op&lt;br /&gt;
         Ellers&lt;br /&gt;
            Tæl en ned&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Koden inde i funktionerne===&lt;br /&gt;
&lt;br /&gt;
Koden er ret uoverskuelig, specielt fordi den skal kunne fungere på 4 forskellige måder, ud fra de indstillinger der er lavet i interface-filen.&lt;br /&gt;
&lt;br /&gt;
Det er også således at noget løses i interrupt, mens andet løses i servicerutinen.&lt;br /&gt;
&lt;br /&gt;
Koden ligger sammen med eksempler og en demo inde i [[media:Rotary_jal.zip|en samlet ZIP-fil]].&lt;br /&gt;
&lt;br /&gt;
==Kodeeksempel til Arduino==&lt;br /&gt;
Dette eksempel er givet for at vise hvordan Rotary Encoderen kan anvendes til Arduino.&lt;br /&gt;
&lt;br /&gt;
Den konkrete kode tager udgangspunkt i pseudokoden, og bliver ikke forklaret i detaljer, men der forklares de ting, der har er specielt for denne kode.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;syntaxHighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
#define CLK_PIN 3&lt;br /&gt;
#define DT_PIN 4&lt;br /&gt;
&lt;br /&gt;
int countValue = 0;&lt;br /&gt;
bool lastClk;&lt;br /&gt;
bool lastDt;&lt;br /&gt;
&lt;br /&gt;
void setup() {&lt;br /&gt;
  pinMode(CLK_PIN, INPUT);&lt;br /&gt;
  pinMode(DT_PIN, INPUT);&lt;br /&gt;
  Serial.begin(500000);&lt;br /&gt;
  delay(100);&lt;br /&gt;
  Serial.println(&amp;quot;\r\nRotary Switch Simple demo&amp;quot;);&lt;br /&gt;
  lastClk = digitalRead(CLK_PIN);&lt;br /&gt;
  lastDt = digitalRead(DT_PIN);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void printCount() {&lt;br /&gt;
    Serial.print(&amp;quot;Count:\t&amp;quot;);&lt;br /&gt;
    Serial.print(countValue);&lt;br /&gt;
    int countClick = countValue / 4;&lt;br /&gt;
    Serial.print(&amp;quot;\t&amp;quot;);&lt;br /&gt;
    Serial.println(countClick);&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
void loop() {&lt;br /&gt;
  bool clkNow = digitalRead(CLK_PIN);&lt;br /&gt;
  bool dtNow = digitalRead(DT_PIN);&lt;br /&gt;
  if (clkNow != lastClk) {&lt;br /&gt;
    if (clkNow) {&lt;br /&gt;
      if (dtNow) {&lt;br /&gt;
        countValue++;&lt;br /&gt;
      } else {&lt;br /&gt;
        countValue--;&lt;br /&gt;
      }&lt;br /&gt;
    } else {&lt;br /&gt;
      if (dtNow) {&lt;br /&gt;
        countValue--;&lt;br /&gt;
      } else {&lt;br /&gt;
        countValue++;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
    lastClk = clkNow;&lt;br /&gt;
    printCount();&lt;br /&gt;
  }&lt;br /&gt;
  if (dtNow != lastDt) {&lt;br /&gt;
    if (dtNow) {&lt;br /&gt;
      if (clkNow) {&lt;br /&gt;
        countValue--;&lt;br /&gt;
      } else {&lt;br /&gt;
        countValue++;&lt;br /&gt;
      }&lt;br /&gt;
    } else {&lt;br /&gt;
      if (clkNow) {&lt;br /&gt;
        countValue++;&lt;br /&gt;
      } else {&lt;br /&gt;
        countValue--;&lt;br /&gt;
      }&lt;br /&gt;
    }&lt;br /&gt;
    lastDt = dtNow;&lt;br /&gt;
    printCount();&lt;br /&gt;
  }&lt;br /&gt;
}&lt;br /&gt;
&amp;lt;/syntaxHighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Koden læser alle skift på de to signaler CLK og DT, og som Rotary Encoderen (den der er testet til koden) er opbygget, så for hvert klik der er i omgangen (20 klik i alt), så er der 4 skift. Når koden skriver ud i Serial monitor, så kommer der udskrift på alle kanter.&lt;br /&gt;
&lt;br /&gt;
Udskriften viser to værdier - tællingen på kanterne og så den tælling delt med 4, som modsvarer de klik der er i Rotary Encoderen.&lt;br /&gt;
Hvis man kun ønskede udskrift for hvert klik, så kunne man i funktionen printCount() starte med følgende linje:&lt;br /&gt;
&amp;lt;syntaxHighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  if ((countValue % 4) != 0) return;&lt;br /&gt;
&amp;lt;/syntaxHighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
I setup() sættes den serielle Baud Rate til 500000. Grunden til dette er at koden i loop() er tidsfølsom, forstået på den måde, at hvis der er noget i loop() der tager lang tid, så kan koden springe over kanter, og dermed ikke tælle rigtigt. Dette blev observeret ved en Baud Rate på 9600, hvor det der skulle skrives ud kom til at vente på at der blev skrevet ud, så signaler blev sprunget over. Måden det blev konstateret var at markere et nulpunkt, og så dreje stille og roligt fx 2 omgange. Dette gav som forventet 160 kanter. Ved så at køre hurtigt to omgange retur skulle man forvente at tallet kom tilbage på 0 - dette var ikke tilfældet, altså var der kanter der blev sprunget over.&lt;br /&gt;
{{moduler}}&lt;br /&gt;
&lt;br /&gt;
{{keyes-moduler}}&lt;br /&gt;
 &lt;br /&gt;
[[Kategori:Flere digitale signaler]]&lt;br /&gt;
[[Kategori:JAL-moduler]]&lt;/div&gt;</summary>
		<author><name>Bar</name></author>
	</entry>
	<entry>
		<id>https://www.htxarduino.dk/index.php?title=Rotary_Encoder&amp;diff=5417</id>
		<title>Rotary Encoder</title>
		<link rel="alternate" type="text/html" href="https://www.htxarduino.dk/index.php?title=Rotary_Encoder&amp;diff=5417"/>
		<updated>2024-05-02T06:45:51Z</updated>

		<summary type="html">&lt;p&gt;Bar: /* Koden inde i funktionerne */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;[[Fil:Modul-24.jpg|thumb|right|200px|Billede af Rotary Encoder modul]]&lt;br /&gt;
&lt;br /&gt;
Rotary Encoder modulet har et skaft på toppen, som kan roteres omkring en lodret akse. Dette skaft kan roteres uendeligt. Modulet kan registrere registrere skaftets rotationer. &lt;br /&gt;
&lt;br /&gt;
Rotary encoders bliver brugt til mange processer, som kræver præcis uendelig rotation. Eksempelvis kan det bruges til computer mus med drejehjul, hvor det skal registreres i hvor meget kuglen drejer og i hvilke retninger. Det kan bruges til robotter, for at registrere hvor meget robotens motorer er drejet. Det kan også bruges i kamerar linser, for at undersøge hvor meget kameraret er zoomet ind.&lt;br /&gt;
&lt;br /&gt;
Siden at modulet kan rotere uendeligt, har den ikke rigtigt nogen start eller slutning, men hvis man, i koden, holder styr på rotationen, så kan man bruge modulet bruges til at skrue op eller ned for noget, eksempelvis volumen af lyd eller styrken af lys lys. Rotary Encoder afgiver kun information når der bliver drejet på skaftet, den kan altså ikke fortælle nuværende position. Hvis man skal have en start position, skal man sætte skaftets nuværende position til start og så vil man derefter kunne skrue op eller ned. Modulet kan dog heller ikke gemme informationer, så når programmet bliver genstartet, vil den igen gøre skaftets nuværende position til start position. Så hvis man ønsker en position, som fast skal være start position, så skal man enten, aldrig lukke programmet eller sætte skaftets position tilbage til start før man starter sit program.&lt;br /&gt;
&lt;br /&gt;
==Benforbindelser til modul==&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!Signal!!pin!!Pic-pin!!Forklaring&lt;br /&gt;
|-&lt;br /&gt;
|GND||1||10||Stel-forbindelse&lt;br /&gt;
|-&lt;br /&gt;
| + ||2||9||+ 5V forsyning&lt;br /&gt;
|-&lt;br /&gt;
|SW||3||5||Kontakt i Rotary Encoder, der trækker mod stel, når den trykkes ind&lt;br /&gt;
|-&lt;br /&gt;
|DT||4||4||Data signal - en del af rotations aftastning&lt;br /&gt;
|-&lt;br /&gt;
|CLK||5||3||Clock signal - en del af rotations aftastning&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
==Princip-diagram for Rotary Encoder==&lt;br /&gt;
{| &lt;br /&gt;
|-&lt;br /&gt;
|valign=&amp;quot;top&amp;quot;|&lt;br /&gt;
&lt;br /&gt;
Selve rotary encoderen er vist som de to switche U$1 og U$2, hvor der sidder to pull-up modstande R2 og R3 der er monteret på printet.&lt;br /&gt;
&lt;br /&gt;
Den sidste del er trykknappen S1, der sidder i drejeakslen, der kan aktiveres ved at trykke akslen indad.&lt;br /&gt;
På printet er der plads til en pull up, men den er ikke monteret, så den kan man eftermontere (SMD), eller man kan placere den uden for printet.&lt;br /&gt;
&lt;br /&gt;
|valign=&amp;quot;top&amp;quot;|&lt;br /&gt;
[[Image:Rotary_diagram.PNG|400px|Principskitse af Rotary Encoder]]&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Forklaring til aflæsning af Rotary Encoder===&lt;br /&gt;
Når man drejer på Rotary Encoderen, så giver den to faseforskudte signaler ud, som vist her:&lt;br /&gt;
&lt;br /&gt;
[[Image:Rotary_full_count.PNG|Tidsdiagram for Rotary Encoder med tælleskridt]]&lt;br /&gt;
&lt;br /&gt;
Som det kan ses på tallene under kurverne, så tæller man et skridt hver gang der kommer en kant i signalerne fra enten CLK eller Data. Når Data er faseforskudt så den kommer efter CLK, så tælles der opad, og når faseforskydningen vender, så Data kommer før CLK, så tælles der nedad.&lt;br /&gt;
&lt;br /&gt;
Mellem hvert &amp;quot;klik&amp;quot; på rotary encoderen tælles enten 4 gange op eller 4 gange ned.&lt;br /&gt;
&lt;br /&gt;
Det kan man anvendelsesmæssigt håndtere ved at dividere tallet med 4.&lt;br /&gt;
&lt;br /&gt;
Man kan også tælle lidt simplere, så man kun ændrer noget, hver gang CLK går fra lav til høj, som det er illustreret her:&lt;br /&gt;
&lt;br /&gt;
[[Image:Rotary_single_count.PNG|Tidsdiagram for Rotary Encoder med enkelt tælling]]&lt;br /&gt;
&lt;br /&gt;
Som det kan ses tælles der ved de positivt gående kanter på CLK, og der tælles op når Data er høj, og ned når Data er lav. &lt;br /&gt;
&lt;br /&gt;
Dette princip virke umiddelbart enkelt, men det kan også have en ulempe, nemlig at der kan tælles forkert, hvis CLK giver flere positive kanter, men Data står på samme niveau, som det er illustreret her:&lt;br /&gt;
&lt;br /&gt;
[[Image:Rotary_single_fejl.PNG|Tidsdiagram for Rotary Encoder med fejltælling]]&lt;br /&gt;
&lt;br /&gt;
==Software modulet Rotary.jal==&lt;br /&gt;
Der ligger en servicerutine i Rotary modulet, hvor man kan få at vide om der er kommet en ny værdi, og den værdi kan aflæses i variablen Rotary_value, der er et signed word, som altså kan antage værdier fra -32768 til 32767.&lt;br /&gt;
&lt;br /&gt;
Ved opstart står Rotary_value på 0.&lt;br /&gt;
&lt;br /&gt;
Modulet kan anvende 4 forskellige principper.&lt;br /&gt;
&lt;br /&gt;
Man kan vælge at arbejde med alle tælleskridt, så der kommer 80 på en omgang, men 4 trin for hvert &amp;quot;klik&amp;quot; på encoderen, eller man kan vælge at aflæse så der kommer 20 på en omgang, men med muligheden for at der opstår fejl.&lt;br /&gt;
&lt;br /&gt;
Man kan også vælge om man vil servicere ved blot at kalde tit nok, eller om man vil lade en interrupt-rutine håndtere aflæsningen. Begge metoder kan kombineres frit uden begrænsninger.&lt;br /&gt;
&lt;br /&gt;
===Anvendelse af Rotary Encoder===&lt;br /&gt;
Når man vil anvende Rotary Encoder modulet, så skal man [[include]] Rotary.jal som følger:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;source lang=&amp;quot;jal&amp;quot;&amp;gt;&lt;br /&gt;
   include Rotary.jal&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Hvis Rotary.jal ligger i \lib inde i c:\jalpack så kan compileren finde modulet.&lt;br /&gt;
&lt;br /&gt;
[[JAL-fil]]en ligger sammen med et par eksempler inde i [[media:Rotary_jal.zip|en samlet ZIP-fil]]&lt;br /&gt;
&lt;br /&gt;
Rotary er testet på følgende kombinationer:&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot; border=&amp;quot;1&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
!PIC!!pin&lt;br /&gt;
|-&lt;br /&gt;
|[[PIC16F684]]||CLK=a2 DT=a3&lt;br /&gt;
|-&lt;br /&gt;
|[[PIC16F690]]||CLK=a2 DT=a3 - med alle kombinationer af interrupt og fuld/enkelt tælling&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
===Interface fil til Rotary Encoder===&lt;br /&gt;
Man kan indstille de beskrevne ting i interfacefilen, samt man kan vælge hvilke indgange man ønsker at anvende til at aflæse encoderen med.&lt;br /&gt;
&lt;br /&gt;
I Rotary_def.jal kan antallet af tælleskridt indstilles ved:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;jal&amp;quot;&amp;gt;&lt;br /&gt;
Const rotary_single = false&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
False giver 4 skridt pr. klik og true giver 1 skridt pr. klik (kan lave fejl).&lt;br /&gt;
&lt;br /&gt;
I Rotary_def.jal kan der indstilles om man skal bruge interrupt ved:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;jal&amp;quot;&amp;gt;&lt;br /&gt;
Const rotary_interrupt = true&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Placeringen af benene er lidt mere kompliceret, specielt på [[PIC16F690]], hvor man både kan bruge ben i PORTA og PORTB til det - dog med den begrænsning at man skal bruge to ben i samme port.&amp;lt;br /&amp;gt;&lt;br /&gt;
Man angiver hvilken port det er  med følgende angivelse:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;jal&amp;quot;&amp;gt;&lt;br /&gt;
alias     Rotary_port                is porta&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Som normalt skal man angive hvilke pins det er ved navnene. Her skal navngives CLK og Data, samt direction-benene for de samme:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;jal&amp;quot;&amp;gt;&lt;br /&gt;
alias     Rotary_pin_clk             is pin_A2      -- clock pin&lt;br /&gt;
alias     Rotary_pin_dt              is pin_A3      -- data pin.&lt;br /&gt;
--&lt;br /&gt;
alias     Rotary_pin_direction_clk   is pin_A2_direction&lt;br /&gt;
alias     Rotary_pin_direction_dt    is pin_A3_direction&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Til indstilling af interruptet skal man angive hvilke interrupt-indstillinger det er:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;jal&amp;quot;&amp;gt;&lt;br /&gt;
alias     Rotary_int_clk             is IOCA_IOCA2&lt;br /&gt;
alias     Rotary_int_dt              is IOCA_IOCA3&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Endelig skal der kunne angives hvilke bit det er i de spejlede variabler inde i rutinerne, og det gøres blot ved at angive bit-nummeret som vist her:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;jal&amp;quot;&amp;gt;&lt;br /&gt;
const     Rotary_clk_bit             = 2&lt;br /&gt;
const     Rotary_dt_bit              = 3&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Anvendelsen af Rotary Encoder==&lt;br /&gt;
&lt;br /&gt;
Man skal foretage valgene omkring interrupt ud fra om man lave sin kode så modulet serviceres meget ofte, og om man skal have visning på alle nye værdier, samt om man må miste værdier (om man har et fast nul-punkt).&lt;br /&gt;
&lt;br /&gt;
Så skal man vælge om man vil have alle tælleskridt med, eller om man vil have 1 tælleskridt pr. klik, med den ulempe, at man kan få falske tællinger.&lt;br /&gt;
&lt;br /&gt;
Ud over det er anvendelsen ret simpel:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;jal&amp;quot;&amp;gt;&lt;br /&gt;
 include Rorary.jal&lt;br /&gt;
&lt;br /&gt;
 forever loop&lt;br /&gt;
   if new_rotary_value then&lt;br /&gt;
      rotary_value  -- anvend den nye værdi til noget fornuftigt&lt;br /&gt;
   end if&lt;br /&gt;
   --&lt;br /&gt;
   -- Her kan placeres anden kode i loopet, der skal lave andre ting&lt;br /&gt;
   --&lt;br /&gt;
 end loop&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Forklaring af Rotary software==&lt;br /&gt;
&lt;br /&gt;
Her forklares i detaljer hvordan modulet fungerer inde i software-modulet&lt;br /&gt;
&lt;br /&gt;
===Initialisering af softwaren===&lt;br /&gt;
&lt;br /&gt;
Initialiseringen kan i [[Pseudokode]] udtrykkes som følger:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
   Læs opsætningen i Rotary_def.jal&lt;br /&gt;
   Sæt Rotary_value til 0&lt;br /&gt;
   indstil interruptet, hvis det skal anvendes&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Funktionen new_rotary_value===&lt;br /&gt;
&lt;br /&gt;
Funktionen kaldes ofte, og når der er en ny værdi, så returnerer den true, og man kan aflæse status på tælleren i rotary_value.&lt;br /&gt;
&lt;br /&gt;
Hvis man ikke anvender interrupt, så skal funktionen kaldes så ofte, at man ikke mister tælleskridt. Anvender man interruptet, så vil der blot ligge den værdi man er kommet til.&lt;br /&gt;
&lt;br /&gt;
===Konstanterne i interface-filen===&lt;br /&gt;
Det er mest af alt de indstillinger der er beskrevet tidligere.&lt;br /&gt;
&lt;br /&gt;
===Funktionsbeskrivelse===&lt;br /&gt;
&lt;br /&gt;
Princippet for at registrere tælling af enkelt skridt kan i [[pseudokode]] udtrykkes som følger:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Hvis der er en forkant på CLK så&lt;br /&gt;
   Marker at der er sket en ændring&lt;br /&gt;
   Hvis Data er høj så&lt;br /&gt;
      Tæl en op&lt;br /&gt;
   ellers&lt;br /&gt;
      Tæl en ned&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dette kan ske direkte i servicerutinen, eller hvis det er med interrupt, så sker det ved at registreringen sker i interruptet, og servicerutinen registrerer at det er sket.&lt;br /&gt;
&lt;br /&gt;
På samme måde laves tællingen på alle kanter enten i interruptet eller i servicerutinen.&amp;lt;br /&amp;gt;&lt;br /&gt;
Som pseudokode er det lidt mere kompliceret:&lt;br /&gt;
&amp;lt;pre&amp;gt;&lt;br /&gt;
Hvis der er sket et skift på CLK så&lt;br /&gt;
   Marker at der er sket en ændring&lt;br /&gt;
   Hvis CLK er Høj så&lt;br /&gt;
      Hvis Data er høj så&lt;br /&gt;
         Tæl en op&lt;br /&gt;
      Ellers&lt;br /&gt;
         Tæl en ned&lt;br /&gt;
   Ellers&lt;br /&gt;
      Hvis Data er høj så&lt;br /&gt;
         Tæl en ned&lt;br /&gt;
      Ellers&lt;br /&gt;
         Tæl en op&lt;br /&gt;
Ellers&lt;br /&gt;
   Hvis der er sket et skift på Data så&lt;br /&gt;
      Marker at der er sket en ændring&lt;br /&gt;
      Hvis Data er Høj så&lt;br /&gt;
         Hvis CLK er høj så&lt;br /&gt;
            Tæl en ned&lt;br /&gt;
         Ellers&lt;br /&gt;
            Tæl en op&lt;br /&gt;
      Ellers&lt;br /&gt;
         Hvis CLK er høj så&lt;br /&gt;
            Tæl en op&lt;br /&gt;
         Ellers&lt;br /&gt;
            Tæl en ned&lt;br /&gt;
&lt;br /&gt;
&amp;lt;/pre&amp;gt;&lt;br /&gt;
&lt;br /&gt;
===Koden inde i funktionerne===&lt;br /&gt;
&lt;br /&gt;
Koden er ret uoverskuelig, specielt fordi den skal kunne fungere på 4 forskellige måder, ud fra de indstillinger der er lavet i interface-filen.&lt;br /&gt;
&lt;br /&gt;
Det er også således at noget løses i interrupt, mens andet løses i servicerutinen.&lt;br /&gt;
&lt;br /&gt;
Koden ligger sammen med eksempler og en demo inde i [[media:Rotary_jal.zip|en samlet ZIP-fil]].&lt;br /&gt;
&lt;br /&gt;
==Kodeeksempel til Arduino==&lt;br /&gt;
Dette eksempel er givet for at vise hvordan Rotary Encoderen kan anvendes til Arduino.&lt;br /&gt;
&lt;br /&gt;
Den konkrete kode tager udgangspunkt i pseudokoden, og bliver ikke forklaret i detaljer, men der forklares de ting, der har er specielt for denne kode.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{{moduler}}&lt;br /&gt;
&lt;br /&gt;
{{keyes-moduler}}&lt;br /&gt;
 &lt;br /&gt;
[[Kategori:Flere digitale signaler]]&lt;br /&gt;
[[Kategori:JAL-moduler]]&lt;/div&gt;</summary>
		<author><name>Bar</name></author>
	</entry>
	<entry>
		<id>https://www.htxarduino.dk/index.php?title=Programmering_med_ChatGPT&amp;diff=5416</id>
		<title>Programmering med ChatGPT</title>
		<link rel="alternate" type="text/html" href="https://www.htxarduino.dk/index.php?title=Programmering_med_ChatGPT&amp;diff=5416"/>
		<updated>2024-04-30T10:50:53Z</updated>

		<summary type="html">&lt;p&gt;Bar: /* Den meget nemmere metode */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Det er ikke så svært at få ChatGPT&amp;lt;ref&amp;gt;[https://chat.openai.com/auth/login ChatGPT Login] - Indgangen til ChatGPT&amp;lt;/ref&amp;gt; til at lave kode, der skal man blot beskrive hvad man gerne vil have programmet til at gøre, og så kopiere den kode, der kommer ud af det - det giver tit ret gode resultater.&lt;br /&gt;
&lt;br /&gt;
Problemet med at anvende ChatGPT i forbindelse med skoleprojekter er, at man skal have forståelsen med i det, og at man ikke kan blive anklaget for plagiat.&lt;br /&gt;
&lt;br /&gt;
==Hvad må man ikke i et skoleprojekt==&lt;br /&gt;
*Man må ikke kopiere kode, som man ikke selv har skrevet, til et programmeringsprodukt uden at man angiver en kilde. Det er uanset hvor koden stammer fra, også selvom man har brugt ChatGPT til at &amp;quot;udvikle&amp;quot; koden.&lt;br /&gt;
*Man må ikke aflevere et produkt hvor de primære dele af koden er kopieret, heller ikke selvom man kildehenviser.&lt;br /&gt;
*Man må ikke få ChatGPT til at dokumentere sin kode, ved at man kopierer ChatGPT&#039;s beskrivelse ind i sin dokumentation af koden.&lt;br /&gt;
&lt;br /&gt;
De beskrevne eksempler er at betragte som plagiat, og vil blive håndteret efter skolens ordensregler, hvilket i værste fald kan ende med at et fag annulleres eller man bliver bortvist fra uddannelsen.&lt;br /&gt;
&lt;br /&gt;
==Hvad er tilladt med ChatGPT==&lt;br /&gt;
På samme måde som man må anvende kilder fra internettet, så må man i programmerings-faget i gymnasiet anvende ChatGPT i udviklingen af kode til et programmeringsprodukt. Dette er blevet tilladt via en revidering af vejledningen til faget&amp;lt;ref&amp;gt;[https://www.uvm.dk/-/media/filer/uvm/udd/gym/pdf23/aug/vejledninger/valgfag/230807-programmering-c--valgfag.pdf Vejledning] til Valgfaget Programmering C&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
I vejledningen står der som følger:&lt;br /&gt;
&lt;br /&gt;
: &#039;&#039;&amp;quot;brug af internettet er tilladt som fagligt hjælpemiddel ved de mundtlige prøver, inkluderer de tilladte hjælpemidler anvendelsen af chatbots og lignende på en måde, som afspejler, hvordan man arbejder i den daglige undervisning. Dette kunne fx være brug af ChatGPT til at debugge kode.&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Det skal altså afspejle den normale brug, som man også har ved at bruge internettet. Som angivet under hvad man ikke må, så er den normale brug, at man anvender information til at lære at programmere, men at man ikke tager så meget af sit produkt fra nettet, så man ikke har en forståelse af hvordan produktet er sammensat.&lt;br /&gt;
&lt;br /&gt;
Videre i vejledningen står der:&lt;br /&gt;
&lt;br /&gt;
: &#039;&#039;&amp;quot;I forhold til denne type hjælpemidler er det vigtigt at være opmærksom på, at den tilladte anvendelse er betinget af, at hjælpemidlerne kun benyttes i et omfang, hvor prøvebesvarelsen er selvstændig og udelukkende elevens egen.&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Igen understreges at det der afleveres skal være elevens selvstændigt udviklede produkt og dokumentation, hvor man på normal vis anvender internettet som et værktøj til at bibringe forståelse.&lt;br /&gt;
&lt;br /&gt;
==Problemet med ChatGPT==&lt;br /&gt;
Ligesom man ikke kan kilde-henvise til &amp;quot;google&amp;quot;, for at angive at man har fundet informationer på nettet, så kan man heller ikke kildehenvise til ChatGPT direkte som en kilde.&lt;br /&gt;
&lt;br /&gt;
Når man finder informationer med google&#039;, så skal man angive hvor på nettet man har fundet dem med så præcis en kildehenvisning, at man kan se den information der er blevet anvendt.&lt;br /&gt;
&lt;br /&gt;
Denne type henvisning kan man ikke lave i forhold til ChatGPT, da sprogmodellen der ligger bag ChatGPT konstant udvikler sig, samt at de svar sprogmodellen giver har et randomiseret element indbygget, som er med til at give bedre svar&amp;lt;ref&amp;gt;[https://www.it-vest.dk/arrangementer/sig-webinar-14-marts-2024-kunstig-intelligens-og-chatgpt-hvordan-virker-det-og-skal-vi-bare-opgive-undervisning-og-eksamen Webinar om kunstig intelligens]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Her er man altså nødt til at tage andre metoder i brug, for at kunne dokumentere at man har udviklet sit produkt ordentligt og redeligt.&lt;br /&gt;
&lt;br /&gt;
==Kildehenvisninger i dokumentation==&lt;br /&gt;
Der kan være forskellige standarder for hvordan man kildehenviser i forskellige uddannelser, dette er skrevet med udgangspunkt i at man anvender Word bibliografi-værktøj og her vist med en Harvard-lignende standard&amp;lt;ref&amp;gt;[https://holstebro-htx.dk/index.php/Word_Kildeliste Kildelister] anvendt i Microsoft Word&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Normal Internet-kilde til kode===&lt;br /&gt;
I dette eksempel er der angivet hvordan man ville dokumentere at man har anvendt kode fra et bibliotek til noget hardware på en [[Arduino]]. I det tænkte eksempel er det en 4 kanals AD-konverter&amp;lt;ref&amp;gt;[https://arduinotech.dk/shop/ads1115-module-4-channel-16-bit-i2c-adc-with-pro-gain-amplifier 4 kanals AD-konverter] fra ArduinoTech&amp;lt;/ref&amp;gt;, der er købt som modul.&lt;br /&gt;
&lt;br /&gt;
For at kunne anvende modulet i koden skal der kommunikeres med modulet på en måde, som er angivet i beskrivelsen af modulet - det er dog ikke nødvendigt at sætte sig ind i den grundlæggende kommunikation, hvis man blot ønsker at få værdier ind i sin software. Som en dokumentation for hvordan man anvender biblioteket kan man skrive følgende:&lt;br /&gt;
&lt;br /&gt;
====Eksempel på dokumentation====&lt;br /&gt;
Til at hente værdierne fra den 4 kanals AD-konverter anvendes et bibliotek fundet på GitHub (Singh, 2018) som kan indlæse de analoge spændinger.&lt;br /&gt;
Til at sætte AD-konverteren rigtigt op, til at kunne læse 4 spændinger, så anvendes eksemplet ”ADS1115_SingleEnded.ino” og i setup skrives følgende kode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
    ads.getAddr_ADS1115(ADS1115_DEFAULT_ADDRESS);   // 0x48, 1001 000 (ADDR = GND)&lt;br /&gt;
    ads.setGain(GAIN_TWO);          // 2x gain   +/- 2.048V  1 bit = 0.0625mV (default)&lt;br /&gt;
    ads.setMode(MODE_CONTIN);       // Continuous conversion mode&lt;br /&gt;
    ads.setRate(RATE_128);          // 128SPS (default)&lt;br /&gt;
    ads.setOSMode(OSMODE_SINGLE);   // Set to start a single-conversion&lt;br /&gt;
    ads.begin();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
I [[loop()]] testes i første omgang, om det kan lade sig gøre at læse de 4 kanaler. Dette gøres ved at afvikle følgende testkode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
    address = ads.ads_i2cAddress;&lt;br /&gt;
    Wire.beginTransmission(address);&lt;br /&gt;
    error = Wire.endTransmission();&lt;br /&gt;
    if (error == 0)&lt;br /&gt;
    {&lt;br /&gt;
        int16_t adc0, adc1, adc2, adc3;&lt;br /&gt;
&lt;br /&gt;
        adc0 = ads.Measure_SingleEnded(0);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 1: &amp;quot;);&lt;br /&gt;
        Serial.println(adc0);&lt;br /&gt;
        adc1 = ads.Measure_SingleEnded(1);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 2: &amp;quot;);&lt;br /&gt;
        Serial.println(adc1);&lt;br /&gt;
        adc2 = ads.Measure_SingleEnded(2);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 3: &amp;quot;);&lt;br /&gt;
        Serial.println(adc2);&lt;br /&gt;
        adc3 = ads.Measure_SingleEnded(3);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 4: &amp;quot;);&lt;br /&gt;
        Serial.println(adc3);&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Denne test giver det ønskede resultat.&lt;br /&gt;
&lt;br /&gt;
Ud fra denne beskrivelse viser man, at man tager andres kode, og anvender ind i sit eget projekt, og man angiver præcist i sin beskrivelse hvad man har taget fra andres kode.&lt;br /&gt;
&lt;br /&gt;
I kildelisten vil kilden optræde på følgende måde:&lt;br /&gt;
&lt;br /&gt;
: Singh, Y., 2018. Arduino Library ADS1115 16 bit 4 channel ADC. [Online] &amp;lt;br /&amp;gt;&lt;br /&gt;
: Available at: https://github.com/ncdcommunity/Arduino_Library_ADS1115_16Bit_4Channel_ADC&amp;lt;br /&amp;gt;&lt;br /&gt;
: [Senest hentet eller vist den 15 marts 2024].&lt;br /&gt;
&lt;br /&gt;
===ChatGPT som kilde til kode===&lt;br /&gt;
Det følgende er skrevet med udgangspunkt i det der er beskrevet på viden.ai&amp;lt;ref&amp;gt;[https://viden.ai/korrekt-kildehenvisning-af-chatgpt/ Korrekt kildehenvisning af ChatGPT]&amp;lt;/ref&amp;gt;. hvor der angives hvordan man kildehenviser, men også lidt om hvordan man håndterer det i tekst - i korte træk, lav et metodeafsnit, beskriv hvad man gør og vær meget redelig, ved at man angiver hvad man har fået af ChatGPT ved at lægge det ved som et bilag.&lt;br /&gt;
&lt;br /&gt;
Hvis man forstår at prompte fornuftigt, så er ChatGPT faktisk ret god til at foreslå kode, der kan anvendes, men ligesom det er plagiat hvis man kopierer fra nettet, så er det plagiat, hvis man lader ChatGPT skrive store dele af ens program for sig.&lt;br /&gt;
&lt;br /&gt;
Som det er formuleret i vejledningen til både programmering C og B, så kan man anvende ChatGPT til hjælp i fejlfinding af kode. For at kunne kildehenvise korrekt til hjælp med fejlfinding, så skal man angive hvad man har promptet til ChatGPT og hvad den har svaret - det kan placeres i bilag.&lt;br /&gt;
&lt;br /&gt;
En anden ting, som også er OK at få hjælp med er, at komme i gang med programmet - det er denne problematik der her gives et eksempel på. I eksemplet beskrives hvad man skal skrive i sin dokumentation, når man har anvendt denne hjælp, og der er forslag til hvordan man kommer videre i projektet.&lt;br /&gt;
&lt;br /&gt;
Konkret er det starten på udviklingen af et lille spil med bolde i et vindue, udviklet i Processing, der tages udgangspunkt i.&lt;br /&gt;
&lt;br /&gt;
====Metodeafsnit med omtale af ChatGPT====&lt;br /&gt;
Når man anvender CharGPT, så skal man dokumentere hvordan man har gjort det, og hvilke overvejelser der ligger bag det. Det betegnes i rapportskrivning som et metodeafsnit. Det kunne i dette eksempel lyde:&lt;br /&gt;
&lt;br /&gt;
For at få en fornuftig start på programkoden er der brugt ChatGPT til at få rammerne på koden etableret, og til at få et system, så der kan optræde flere bolde i programvinduet. Det er ChatGPT 3.5 (OpenAI, 2023)&amp;lt;ref&amp;gt;[https://chat.openai.com/chat Indgangen til ChatGPT 3.5]&amp;lt;/ref&amp;gt; der er anvendt til denne hjælp. Til programstarten blev der promptet efter at få et programvindue på 800x600 hvor en bold bevæger sig rundt. Den foreslåede kode blev kopieret ind i processings IDE (Processing, 2024)&amp;lt;ref&amp;gt;[https://processing.org Hovedsiden for Processing]&amp;lt;/ref&amp;gt; og testet – den opførte sig som forventet.&lt;br /&gt;
&lt;br /&gt;
Derefter blev der promptet efter at få den bold der bevægede sig til at dele sig op i to, når man klikker på den med musen. Dette resulterede i en væsentligt anderledes kode, som igen blev kopieret ind i processing og testet, og igen med et acceptabelt resultat. Dialogen med ChatGPT (OpenAI, 2023) og herunder de to koder, kan ses i bilag 1.&lt;br /&gt;
&lt;br /&gt;
Herefter er resten af koden udviklet på traditionel vis, hvor første trin var at dokumentere princippet i den foreslåede kode, specielt den Ball klasse der blev introduceret for at kunne arbejde med flere bolde i vinduet.&lt;br /&gt;
&lt;br /&gt;
Det nævnte bilag 1 [[media:ChatGPT-dialog-1.pdf|kan ses i denne PDF]].&lt;br /&gt;
&lt;br /&gt;
Når man opretter kilden i Word, så er det lidt forskelligt hvilke felter der er synlige, alt efter hvilken standard man har aktiv - men ved Harvard-Anglia standarden kan indtastningerne se således ud:&lt;br /&gt;
&lt;br /&gt;
[[fil:citat-ChatGPT.png|Indtastningerne ved kildehenvisning til ChatGPT|600px]]&amp;lt;br /&amp;gt;&#039;&#039;Indtastningerne ved kildehenvisning til ChatGPT&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Mere om teknikken i at anvende kildelister kan ses på [https://holstebro-htx.dk/index.php/Word_Kildeliste Holstebro HTX Wiki - Kildelister].&lt;br /&gt;
&lt;br /&gt;
====Den meget nemmere metode====&lt;br /&gt;
Tingene udvikler sig hele tiden, og nu kan man faktisk få et link til den dialog man har haft med ChatGPT 3.5. Hvordan andre sprogmodeller fungerer må man selv eksperimentere sig frem til.&lt;br /&gt;
&lt;br /&gt;
Måden man gør det på er, at man klikker på en ikon i øverste højre side af websiden med den dialog man gerne vil linke til, som vist herunder, hvor man kommer i en dialog, så man kan kopiere linket.&amp;lt;br /&amp;gt;&lt;br /&gt;
[[fil:link_til_chatGPT.png|Link ikon til dialog i chatGPT]]&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Link ikon til dialog i chatGPT&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Selve linket ser ud som følger: https://chat.openai.com/share/90e9607f-bff9-40d1-a68c-9617051e9615.&lt;br /&gt;
&lt;br /&gt;
====Dokumentation af koden udviklet af ChatGPT====&lt;br /&gt;
Da der skulle kunne dannes nye bolde så oprettes der en klasse, som ChatGPT skriver det i dialogen i Bilag 1:&lt;br /&gt;
&lt;br /&gt;
: &#039;&#039;&amp;quot;Dette kodeeksempel opretter en klasse kaldet Ball, som repræsenterer boldobjekterne. Når musen klikkes, kontrolleres det, om musens position er inden for en bold. Hvis det er tilfældet, oprettes to nye boldobjekter, der bevæger sig i forskellige retninger, og den originale bold fjernes fra arrayet.&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Ved at teste koden kan man se at det ikke er det helt rigtige den formulerer - der oprettes godt nok to nye bold-objekter, men det er ikke den oprindelige bold der fjernes, det er den ene af de ny-oprettede bolde. Det kan ses ved at de to bolde kommer i samme position, og den ene fortsætter i samme retning (den oprindelige), mens den ny-oprettede går i en tilfældig retning. Dette rettes til senere i dokumentationen under &amp;quot;oprettelse af ny bold&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
For at have en god struktur i koden, så placeres klassen Ball i en fil for sig kaldet Ball. Denne fil starter med at definere koden som en klasse med linjen:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
class Ball {&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dernæst defineres klassens egenskaber, der er boldens position og hastighed samt en fast diameter. Ud over det er der en x- og y-retning defineret. Den anvendes til at sige om bolden bevæger sig i en positiv eller negativ retning, så de skifter mellem +1 og -1, når kanterne rammes.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  float x, y;&lt;br /&gt;
  float xspeed, yspeed;&lt;br /&gt;
  int diameter = 30;&lt;br /&gt;
  int xdirection = 1;&lt;br /&gt;
  int ydirection = 1;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der defineres to forskellige constructors til bolden. Den første anvendes til at danne den første bold med, hvor position og hastighed sættes tilfældigt.&lt;br /&gt;
&lt;br /&gt;
Her forudses et problem at der kan komme et randfænomen, hvis bolden dannes, så den ligger med noget uden for skærmen. Da det er tilfældigt; så er det sjældent problemet opstår. For at fremprovokere det oftere er det testet med en diameter på 200, hvor det kunne ses at bolden bliver &amp;quot;hængende&amp;quot; i kanten.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  Ball() {&lt;br /&gt;
    x = random(width);&lt;br /&gt;
    y = random(height);&lt;br /&gt;
    xspeed = random(0.5, 2);&lt;br /&gt;
    yspeed = random(0.5, 2);&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Dette rettes ved at omskrive den foreslåede constructor til følgende kode, hvor bolden placeres mindst en halv diameter fra kanten:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  Ball() {&lt;br /&gt;
    x = random(diameter / 2, width - diameter / 2);&lt;br /&gt;
    y = random(diameter / 2, height - diameter / 2);&lt;br /&gt;
    xspeed = random(0.5, 2);&lt;br /&gt;
    yspeed = random(0.5, 2);&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Den anden constructor tager fire parametre, der er positionen og hastigheden. Denne constructor anvendes, når der skal dannes nye bolde, hvor koden netop skal starte den nye bold i den oprindelige bolds position, og med en ny retning.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  Ball(float x, float y, float xspeed, float yspeed) {&lt;br /&gt;
    this.x = x;&lt;br /&gt;
    this.y = y;&lt;br /&gt;
    this.xspeed = xspeed;&lt;br /&gt;
    this.yspeed = yspeed;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ud over disse standard ting til oprettelsen af objekter, så er der 3 metoder i klassen. Den første er en move() metode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  void move() {&lt;br /&gt;
    x = x + (xspeed * xdirection);&lt;br /&gt;
    y = y + (yspeed * ydirection);&lt;br /&gt;
&lt;br /&gt;
    if ((x + diameter/2 &amp;gt;= width) || (x - diameter/2 &amp;lt;= 0)) {&lt;br /&gt;
      xdirection *= -1;&lt;br /&gt;
    }&lt;br /&gt;
    if ((y + diameter/2 &amp;gt;= height) || (y - diameter/2 &amp;lt;= 0)) {&lt;br /&gt;
      ydirection *= -1;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Måden metoden virker på er at den lægger hastigheden til boldens position (både x og y), og hvis boldens position (både i x og y) er kommet uden for rammen, så ændres retningen for enten x eller y.&lt;br /&gt;
&lt;br /&gt;
For at kunne vise bolden er der en display() metode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  void display() {&lt;br /&gt;
    ellipse(x, y, diameter, diameter);&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Den sidste metode hedder contains(), og den tager en position som parameter til metoden. Der undersøges så om den position ligger inden for bolden ved at se om afstanden mellem boldens center og den testede position er mindre end den halve diameter. Hvis den er inden for bolden, så returneres true, ellers returneres false:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  boolean contains(float x, float y) {&lt;br /&gt;
    float d = dist(x, y, this.x, this.y);&lt;br /&gt;
    if (d &amp;lt; diameter/2) {&lt;br /&gt;
      return true;&lt;br /&gt;
    } else {&lt;br /&gt;
      return false;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Oprettelse af ny bold====&lt;br /&gt;
I den oprindelige kode undersøges om der er klikket på en bold, ved at alle bolde løbes igennem i mousePressed() funktionen, og med metoden contains undersøges om der er klikket på en bold. Denne måde at undersøge alle bolde på beholdes.&lt;br /&gt;
&lt;br /&gt;
Som omtalt er det ikke den smarteste måde til at dele bolden op i to, der anvendes. Som det ses i koden herunder, så appendes der to nye bolde på med den oprindelige bolds x- og y-position på samt tilfældige x- og y-hastigheder. Disse to bolde lægges i slutningen af arrayet. Derefter anvendes shorten&amp;lt;ref&amp;gt;[https://processing.org/reference/shorten_.html Processings shorten metode til arrays]&amp;lt;/ref&amp;gt; til at fjerne et element, men da det element der fjernes er det sidste element i arrayet, så fjernes der bare den sidst oprettede bold.&lt;br /&gt;
&lt;br /&gt;
Hvis man var tilfreds med den opførsel, så kunne man blot fjerne kodelinjen med den anden append og kodelinjen med shorten. Så ville man have samme funktion.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
    if (balls[i].contains(mouseX, mouseY)) {&lt;br /&gt;
      balls = (Ball[]) append(balls, new Ball(balls[i].x, balls[i].y, random(-5, 5), random(-5, 5)));&lt;br /&gt;
      balls = (Ball[]) append(balls, new Ball(balls[i].x, balls[i].y, random(-5, 5), random(-5, 5)));&lt;br /&gt;
      balls = (Ball[]) shorten(balls);&lt;br /&gt;
      break;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Den nye bold der oprettes får bare en tilfældig retning, og den oprindelige bold fortsætter bare i den retning den var på vej i. Det er ikke den opførsel der ønskes i spillet. Der ønskes i stedet at det ser ud som om bolden &amp;quot;splittes op&amp;quot; i 2 bolde, og den opførsel laves ved at lade den oprindelige bold ændre 30 grader til den ene side, og den nye bold får 30 grader til den anden side.&lt;br /&gt;
&lt;br /&gt;
For at gøre dette, så oprettes der en metode multiply() i klassen Ball. Denne metode returnerer en ny bold af typen Ball, så nu kan koden i museklikket skrives som følger:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
    if (balls[i].contains(mouseX, mouseY)) {&lt;br /&gt;
      balls = (Ball[]) append(balls, balls[i].multiply());&lt;br /&gt;
      break;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Som det kan ses, så appendes der en ny bold ind i balls-arrayet, ud fra metoden multiply().&lt;br /&gt;
&lt;br /&gt;
Metoden multiply() oprettes inde i klassen med følgende kode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  Ball multiply() {&lt;br /&gt;
    xspeed *= xdirection;&lt;br /&gt;
    yspeed *= ydirection;&lt;br /&gt;
    xdirection = 1;&lt;br /&gt;
    ydirection = 1;&lt;br /&gt;
    float speed = dist(0, 0, xspeed, yspeed);&lt;br /&gt;
    float angle = acos(xspeed / speed);&lt;br /&gt;
    if (yspeed &amp;lt; 0) angle = 0.0 - angle;&lt;br /&gt;
    speed *= 1.5;&lt;br /&gt;
    xspeed = speed * cos(angle + PI / 6);&lt;br /&gt;
    yspeed = speed * sin(angle + PI / 6);&lt;br /&gt;
    Ball b = new Ball(x, y, speed * cos(angle - PI / 6), speed * sin(angle - PI / 6));&lt;br /&gt;
    return b;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Først regnes retningen over i xspeed og yspeed, så de kan være både positive og negative. På den måde indeholder de to variabler retningen.&lt;br /&gt;
&lt;br /&gt;
Dernæst omregnes x- og y-hastigheden til en samlet hastighed speed og en vinkel angle, som kan være mellem +PI og -PI (+/- 180 grader).&lt;br /&gt;
&lt;br /&gt;
Begge bolde skal bevæge sig hurtigere efter de er delt, så spillet gradvist bliver sværere, derfor ganges hastigheden med 1,5.&lt;br /&gt;
&lt;br /&gt;
Den oprindelige bold får nu en ny retning, ved at udregne x- og y-hastigheden ud fra den nye hastighed og vinklen plus 30 grader.&lt;br /&gt;
&lt;br /&gt;
Til sidst oprettes en ny bold med samme position som den oprindelige og en x- og y-hastighed udregnet fra den oprindelige bolds hastighed og vinklen minus 30 grader. Denne bold returneres fra metoden.&lt;br /&gt;
&lt;br /&gt;
==Refleksioner over anvendelsen==&lt;br /&gt;
Der er selvfølgelig stadig lang vej til man har et færdigt spil, men ideen var også at tage fat i, hvordan man anvender ChatGPT på en ordentlig og redelig måde i et programmeringsprojekt. Dette kan selvfølgelig altid gradbøjes, men hvis man håndterer anvendelsen som vist i eksemplet, så vil man ikke gøre noget der kommer i nærheden af plagiat.&lt;br /&gt;
&lt;br /&gt;
==Referencer== &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt; &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Programmering}}&lt;br /&gt;
&lt;br /&gt;
[[Kategori:Programmering teknik]]&lt;/div&gt;</summary>
		<author><name>Bar</name></author>
	</entry>
	<entry>
		<id>https://www.htxarduino.dk/index.php?title=Programmering_med_ChatGPT&amp;diff=5415</id>
		<title>Programmering med ChatGPT</title>
		<link rel="alternate" type="text/html" href="https://www.htxarduino.dk/index.php?title=Programmering_med_ChatGPT&amp;diff=5415"/>
		<updated>2024-04-30T10:50:07Z</updated>

		<summary type="html">&lt;p&gt;Bar: /* Den meget nemmere metode */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Det er ikke så svært at få ChatGPT&amp;lt;ref&amp;gt;[https://chat.openai.com/auth/login ChatGPT Login] - Indgangen til ChatGPT&amp;lt;/ref&amp;gt; til at lave kode, der skal man blot beskrive hvad man gerne vil have programmet til at gøre, og så kopiere den kode, der kommer ud af det - det giver tit ret gode resultater.&lt;br /&gt;
&lt;br /&gt;
Problemet med at anvende ChatGPT i forbindelse med skoleprojekter er, at man skal have forståelsen med i det, og at man ikke kan blive anklaget for plagiat.&lt;br /&gt;
&lt;br /&gt;
==Hvad må man ikke i et skoleprojekt==&lt;br /&gt;
*Man må ikke kopiere kode, som man ikke selv har skrevet, til et programmeringsprodukt uden at man angiver en kilde. Det er uanset hvor koden stammer fra, også selvom man har brugt ChatGPT til at &amp;quot;udvikle&amp;quot; koden.&lt;br /&gt;
*Man må ikke aflevere et produkt hvor de primære dele af koden er kopieret, heller ikke selvom man kildehenviser.&lt;br /&gt;
*Man må ikke få ChatGPT til at dokumentere sin kode, ved at man kopierer ChatGPT&#039;s beskrivelse ind i sin dokumentation af koden.&lt;br /&gt;
&lt;br /&gt;
De beskrevne eksempler er at betragte som plagiat, og vil blive håndteret efter skolens ordensregler, hvilket i værste fald kan ende med at et fag annulleres eller man bliver bortvist fra uddannelsen.&lt;br /&gt;
&lt;br /&gt;
==Hvad er tilladt med ChatGPT==&lt;br /&gt;
På samme måde som man må anvende kilder fra internettet, så må man i programmerings-faget i gymnasiet anvende ChatGPT i udviklingen af kode til et programmeringsprodukt. Dette er blevet tilladt via en revidering af vejledningen til faget&amp;lt;ref&amp;gt;[https://www.uvm.dk/-/media/filer/uvm/udd/gym/pdf23/aug/vejledninger/valgfag/230807-programmering-c--valgfag.pdf Vejledning] til Valgfaget Programmering C&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
I vejledningen står der som følger:&lt;br /&gt;
&lt;br /&gt;
: &#039;&#039;&amp;quot;brug af internettet er tilladt som fagligt hjælpemiddel ved de mundtlige prøver, inkluderer de tilladte hjælpemidler anvendelsen af chatbots og lignende på en måde, som afspejler, hvordan man arbejder i den daglige undervisning. Dette kunne fx være brug af ChatGPT til at debugge kode.&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Det skal altså afspejle den normale brug, som man også har ved at bruge internettet. Som angivet under hvad man ikke må, så er den normale brug, at man anvender information til at lære at programmere, men at man ikke tager så meget af sit produkt fra nettet, så man ikke har en forståelse af hvordan produktet er sammensat.&lt;br /&gt;
&lt;br /&gt;
Videre i vejledningen står der:&lt;br /&gt;
&lt;br /&gt;
: &#039;&#039;&amp;quot;I forhold til denne type hjælpemidler er det vigtigt at være opmærksom på, at den tilladte anvendelse er betinget af, at hjælpemidlerne kun benyttes i et omfang, hvor prøvebesvarelsen er selvstændig og udelukkende elevens egen.&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Igen understreges at det der afleveres skal være elevens selvstændigt udviklede produkt og dokumentation, hvor man på normal vis anvender internettet som et værktøj til at bibringe forståelse.&lt;br /&gt;
&lt;br /&gt;
==Problemet med ChatGPT==&lt;br /&gt;
Ligesom man ikke kan kilde-henvise til &amp;quot;google&amp;quot;, for at angive at man har fundet informationer på nettet, så kan man heller ikke kildehenvise til ChatGPT direkte som en kilde.&lt;br /&gt;
&lt;br /&gt;
Når man finder informationer med google&#039;, så skal man angive hvor på nettet man har fundet dem med så præcis en kildehenvisning, at man kan se den information der er blevet anvendt.&lt;br /&gt;
&lt;br /&gt;
Denne type henvisning kan man ikke lave i forhold til ChatGPT, da sprogmodellen der ligger bag ChatGPT konstant udvikler sig, samt at de svar sprogmodellen giver har et randomiseret element indbygget, som er med til at give bedre svar&amp;lt;ref&amp;gt;[https://www.it-vest.dk/arrangementer/sig-webinar-14-marts-2024-kunstig-intelligens-og-chatgpt-hvordan-virker-det-og-skal-vi-bare-opgive-undervisning-og-eksamen Webinar om kunstig intelligens]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Her er man altså nødt til at tage andre metoder i brug, for at kunne dokumentere at man har udviklet sit produkt ordentligt og redeligt.&lt;br /&gt;
&lt;br /&gt;
==Kildehenvisninger i dokumentation==&lt;br /&gt;
Der kan være forskellige standarder for hvordan man kildehenviser i forskellige uddannelser, dette er skrevet med udgangspunkt i at man anvender Word bibliografi-værktøj og her vist med en Harvard-lignende standard&amp;lt;ref&amp;gt;[https://holstebro-htx.dk/index.php/Word_Kildeliste Kildelister] anvendt i Microsoft Word&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Normal Internet-kilde til kode===&lt;br /&gt;
I dette eksempel er der angivet hvordan man ville dokumentere at man har anvendt kode fra et bibliotek til noget hardware på en [[Arduino]]. I det tænkte eksempel er det en 4 kanals AD-konverter&amp;lt;ref&amp;gt;[https://arduinotech.dk/shop/ads1115-module-4-channel-16-bit-i2c-adc-with-pro-gain-amplifier 4 kanals AD-konverter] fra ArduinoTech&amp;lt;/ref&amp;gt;, der er købt som modul.&lt;br /&gt;
&lt;br /&gt;
For at kunne anvende modulet i koden skal der kommunikeres med modulet på en måde, som er angivet i beskrivelsen af modulet - det er dog ikke nødvendigt at sætte sig ind i den grundlæggende kommunikation, hvis man blot ønsker at få værdier ind i sin software. Som en dokumentation for hvordan man anvender biblioteket kan man skrive følgende:&lt;br /&gt;
&lt;br /&gt;
====Eksempel på dokumentation====&lt;br /&gt;
Til at hente værdierne fra den 4 kanals AD-konverter anvendes et bibliotek fundet på GitHub (Singh, 2018) som kan indlæse de analoge spændinger.&lt;br /&gt;
Til at sætte AD-konverteren rigtigt op, til at kunne læse 4 spændinger, så anvendes eksemplet ”ADS1115_SingleEnded.ino” og i setup skrives følgende kode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
    ads.getAddr_ADS1115(ADS1115_DEFAULT_ADDRESS);   // 0x48, 1001 000 (ADDR = GND)&lt;br /&gt;
    ads.setGain(GAIN_TWO);          // 2x gain   +/- 2.048V  1 bit = 0.0625mV (default)&lt;br /&gt;
    ads.setMode(MODE_CONTIN);       // Continuous conversion mode&lt;br /&gt;
    ads.setRate(RATE_128);          // 128SPS (default)&lt;br /&gt;
    ads.setOSMode(OSMODE_SINGLE);   // Set to start a single-conversion&lt;br /&gt;
    ads.begin();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
I [[loop()]] testes i første omgang, om det kan lade sig gøre at læse de 4 kanaler. Dette gøres ved at afvikle følgende testkode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
    address = ads.ads_i2cAddress;&lt;br /&gt;
    Wire.beginTransmission(address);&lt;br /&gt;
    error = Wire.endTransmission();&lt;br /&gt;
    if (error == 0)&lt;br /&gt;
    {&lt;br /&gt;
        int16_t adc0, adc1, adc2, adc3;&lt;br /&gt;
&lt;br /&gt;
        adc0 = ads.Measure_SingleEnded(0);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 1: &amp;quot;);&lt;br /&gt;
        Serial.println(adc0);&lt;br /&gt;
        adc1 = ads.Measure_SingleEnded(1);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 2: &amp;quot;);&lt;br /&gt;
        Serial.println(adc1);&lt;br /&gt;
        adc2 = ads.Measure_SingleEnded(2);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 3: &amp;quot;);&lt;br /&gt;
        Serial.println(adc2);&lt;br /&gt;
        adc3 = ads.Measure_SingleEnded(3);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 4: &amp;quot;);&lt;br /&gt;
        Serial.println(adc3);&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Denne test giver det ønskede resultat.&lt;br /&gt;
&lt;br /&gt;
Ud fra denne beskrivelse viser man, at man tager andres kode, og anvender ind i sit eget projekt, og man angiver præcist i sin beskrivelse hvad man har taget fra andres kode.&lt;br /&gt;
&lt;br /&gt;
I kildelisten vil kilden optræde på følgende måde:&lt;br /&gt;
&lt;br /&gt;
: Singh, Y., 2018. Arduino Library ADS1115 16 bit 4 channel ADC. [Online] &amp;lt;br /&amp;gt;&lt;br /&gt;
: Available at: https://github.com/ncdcommunity/Arduino_Library_ADS1115_16Bit_4Channel_ADC&amp;lt;br /&amp;gt;&lt;br /&gt;
: [Senest hentet eller vist den 15 marts 2024].&lt;br /&gt;
&lt;br /&gt;
===ChatGPT som kilde til kode===&lt;br /&gt;
Det følgende er skrevet med udgangspunkt i det der er beskrevet på viden.ai&amp;lt;ref&amp;gt;[https://viden.ai/korrekt-kildehenvisning-af-chatgpt/ Korrekt kildehenvisning af ChatGPT]&amp;lt;/ref&amp;gt;. hvor der angives hvordan man kildehenviser, men også lidt om hvordan man håndterer det i tekst - i korte træk, lav et metodeafsnit, beskriv hvad man gør og vær meget redelig, ved at man angiver hvad man har fået af ChatGPT ved at lægge det ved som et bilag.&lt;br /&gt;
&lt;br /&gt;
Hvis man forstår at prompte fornuftigt, så er ChatGPT faktisk ret god til at foreslå kode, der kan anvendes, men ligesom det er plagiat hvis man kopierer fra nettet, så er det plagiat, hvis man lader ChatGPT skrive store dele af ens program for sig.&lt;br /&gt;
&lt;br /&gt;
Som det er formuleret i vejledningen til både programmering C og B, så kan man anvende ChatGPT til hjælp i fejlfinding af kode. For at kunne kildehenvise korrekt til hjælp med fejlfinding, så skal man angive hvad man har promptet til ChatGPT og hvad den har svaret - det kan placeres i bilag.&lt;br /&gt;
&lt;br /&gt;
En anden ting, som også er OK at få hjælp med er, at komme i gang med programmet - det er denne problematik der her gives et eksempel på. I eksemplet beskrives hvad man skal skrive i sin dokumentation, når man har anvendt denne hjælp, og der er forslag til hvordan man kommer videre i projektet.&lt;br /&gt;
&lt;br /&gt;
Konkret er det starten på udviklingen af et lille spil med bolde i et vindue, udviklet i Processing, der tages udgangspunkt i.&lt;br /&gt;
&lt;br /&gt;
====Metodeafsnit med omtale af ChatGPT====&lt;br /&gt;
Når man anvender CharGPT, så skal man dokumentere hvordan man har gjort det, og hvilke overvejelser der ligger bag det. Det betegnes i rapportskrivning som et metodeafsnit. Det kunne i dette eksempel lyde:&lt;br /&gt;
&lt;br /&gt;
For at få en fornuftig start på programkoden er der brugt ChatGPT til at få rammerne på koden etableret, og til at få et system, så der kan optræde flere bolde i programvinduet. Det er ChatGPT 3.5 (OpenAI, 2023)&amp;lt;ref&amp;gt;[https://chat.openai.com/chat Indgangen til ChatGPT 3.5]&amp;lt;/ref&amp;gt; der er anvendt til denne hjælp. Til programstarten blev der promptet efter at få et programvindue på 800x600 hvor en bold bevæger sig rundt. Den foreslåede kode blev kopieret ind i processings IDE (Processing, 2024)&amp;lt;ref&amp;gt;[https://processing.org Hovedsiden for Processing]&amp;lt;/ref&amp;gt; og testet – den opførte sig som forventet.&lt;br /&gt;
&lt;br /&gt;
Derefter blev der promptet efter at få den bold der bevægede sig til at dele sig op i to, når man klikker på den med musen. Dette resulterede i en væsentligt anderledes kode, som igen blev kopieret ind i processing og testet, og igen med et acceptabelt resultat. Dialogen med ChatGPT (OpenAI, 2023) og herunder de to koder, kan ses i bilag 1.&lt;br /&gt;
&lt;br /&gt;
Herefter er resten af koden udviklet på traditionel vis, hvor første trin var at dokumentere princippet i den foreslåede kode, specielt den Ball klasse der blev introduceret for at kunne arbejde med flere bolde i vinduet.&lt;br /&gt;
&lt;br /&gt;
Det nævnte bilag 1 [[media:ChatGPT-dialog-1.pdf|kan ses i denne PDF]].&lt;br /&gt;
&lt;br /&gt;
Når man opretter kilden i Word, så er det lidt forskelligt hvilke felter der er synlige, alt efter hvilken standard man har aktiv - men ved Harvard-Anglia standarden kan indtastningerne se således ud:&lt;br /&gt;
&lt;br /&gt;
[[fil:citat-ChatGPT.png|Indtastningerne ved kildehenvisning til ChatGPT|600px]]&amp;lt;br /&amp;gt;&#039;&#039;Indtastningerne ved kildehenvisning til ChatGPT&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Mere om teknikken i at anvende kildelister kan ses på [https://holstebro-htx.dk/index.php/Word_Kildeliste Holstebro HTX Wiki - Kildelister].&lt;br /&gt;
&lt;br /&gt;
====Den meget nemmere metode====&lt;br /&gt;
Tingene udvikler sig hele tiden, og nu kan man faktisk få et link til den dialog man har haft med ChatGPT 3.5.&lt;br /&gt;
&lt;br /&gt;
Måden man gør det på er, at man klikker på en ikon i øverste højre side af websiden med den dialog man gerne vil linke til, som vist herunder, hvor man kommer i en dialog, så man kan kopiere linket.&amp;lt;br /&amp;gt;&lt;br /&gt;
[[fil:link_til_chatGPT.png|Link ikon til dialog i chatGPT]]&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;Link ikon til dialog i chatGPT&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Selve linket ser ud som følger: https://chat.openai.com/share/90e9607f-bff9-40d1-a68c-9617051e9615.&lt;br /&gt;
&lt;br /&gt;
====Dokumentation af koden udviklet af ChatGPT====&lt;br /&gt;
Da der skulle kunne dannes nye bolde så oprettes der en klasse, som ChatGPT skriver det i dialogen i Bilag 1:&lt;br /&gt;
&lt;br /&gt;
: &#039;&#039;&amp;quot;Dette kodeeksempel opretter en klasse kaldet Ball, som repræsenterer boldobjekterne. Når musen klikkes, kontrolleres det, om musens position er inden for en bold. Hvis det er tilfældet, oprettes to nye boldobjekter, der bevæger sig i forskellige retninger, og den originale bold fjernes fra arrayet.&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Ved at teste koden kan man se at det ikke er det helt rigtige den formulerer - der oprettes godt nok to nye bold-objekter, men det er ikke den oprindelige bold der fjernes, det er den ene af de ny-oprettede bolde. Det kan ses ved at de to bolde kommer i samme position, og den ene fortsætter i samme retning (den oprindelige), mens den ny-oprettede går i en tilfældig retning. Dette rettes til senere i dokumentationen under &amp;quot;oprettelse af ny bold&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
For at have en god struktur i koden, så placeres klassen Ball i en fil for sig kaldet Ball. Denne fil starter med at definere koden som en klasse med linjen:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
class Ball {&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dernæst defineres klassens egenskaber, der er boldens position og hastighed samt en fast diameter. Ud over det er der en x- og y-retning defineret. Den anvendes til at sige om bolden bevæger sig i en positiv eller negativ retning, så de skifter mellem +1 og -1, når kanterne rammes.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  float x, y;&lt;br /&gt;
  float xspeed, yspeed;&lt;br /&gt;
  int diameter = 30;&lt;br /&gt;
  int xdirection = 1;&lt;br /&gt;
  int ydirection = 1;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der defineres to forskellige constructors til bolden. Den første anvendes til at danne den første bold med, hvor position og hastighed sættes tilfældigt.&lt;br /&gt;
&lt;br /&gt;
Her forudses et problem at der kan komme et randfænomen, hvis bolden dannes, så den ligger med noget uden for skærmen. Da det er tilfældigt; så er det sjældent problemet opstår. For at fremprovokere det oftere er det testet med en diameter på 200, hvor det kunne ses at bolden bliver &amp;quot;hængende&amp;quot; i kanten.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  Ball() {&lt;br /&gt;
    x = random(width);&lt;br /&gt;
    y = random(height);&lt;br /&gt;
    xspeed = random(0.5, 2);&lt;br /&gt;
    yspeed = random(0.5, 2);&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Dette rettes ved at omskrive den foreslåede constructor til følgende kode, hvor bolden placeres mindst en halv diameter fra kanten:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  Ball() {&lt;br /&gt;
    x = random(diameter / 2, width - diameter / 2);&lt;br /&gt;
    y = random(diameter / 2, height - diameter / 2);&lt;br /&gt;
    xspeed = random(0.5, 2);&lt;br /&gt;
    yspeed = random(0.5, 2);&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Den anden constructor tager fire parametre, der er positionen og hastigheden. Denne constructor anvendes, når der skal dannes nye bolde, hvor koden netop skal starte den nye bold i den oprindelige bolds position, og med en ny retning.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  Ball(float x, float y, float xspeed, float yspeed) {&lt;br /&gt;
    this.x = x;&lt;br /&gt;
    this.y = y;&lt;br /&gt;
    this.xspeed = xspeed;&lt;br /&gt;
    this.yspeed = yspeed;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ud over disse standard ting til oprettelsen af objekter, så er der 3 metoder i klassen. Den første er en move() metode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  void move() {&lt;br /&gt;
    x = x + (xspeed * xdirection);&lt;br /&gt;
    y = y + (yspeed * ydirection);&lt;br /&gt;
&lt;br /&gt;
    if ((x + diameter/2 &amp;gt;= width) || (x - diameter/2 &amp;lt;= 0)) {&lt;br /&gt;
      xdirection *= -1;&lt;br /&gt;
    }&lt;br /&gt;
    if ((y + diameter/2 &amp;gt;= height) || (y - diameter/2 &amp;lt;= 0)) {&lt;br /&gt;
      ydirection *= -1;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Måden metoden virker på er at den lægger hastigheden til boldens position (både x og y), og hvis boldens position (både i x og y) er kommet uden for rammen, så ændres retningen for enten x eller y.&lt;br /&gt;
&lt;br /&gt;
For at kunne vise bolden er der en display() metode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  void display() {&lt;br /&gt;
    ellipse(x, y, diameter, diameter);&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Den sidste metode hedder contains(), og den tager en position som parameter til metoden. Der undersøges så om den position ligger inden for bolden ved at se om afstanden mellem boldens center og den testede position er mindre end den halve diameter. Hvis den er inden for bolden, så returneres true, ellers returneres false:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  boolean contains(float x, float y) {&lt;br /&gt;
    float d = dist(x, y, this.x, this.y);&lt;br /&gt;
    if (d &amp;lt; diameter/2) {&lt;br /&gt;
      return true;&lt;br /&gt;
    } else {&lt;br /&gt;
      return false;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Oprettelse af ny bold====&lt;br /&gt;
I den oprindelige kode undersøges om der er klikket på en bold, ved at alle bolde løbes igennem i mousePressed() funktionen, og med metoden contains undersøges om der er klikket på en bold. Denne måde at undersøge alle bolde på beholdes.&lt;br /&gt;
&lt;br /&gt;
Som omtalt er det ikke den smarteste måde til at dele bolden op i to, der anvendes. Som det ses i koden herunder, så appendes der to nye bolde på med den oprindelige bolds x- og y-position på samt tilfældige x- og y-hastigheder. Disse to bolde lægges i slutningen af arrayet. Derefter anvendes shorten&amp;lt;ref&amp;gt;[https://processing.org/reference/shorten_.html Processings shorten metode til arrays]&amp;lt;/ref&amp;gt; til at fjerne et element, men da det element der fjernes er det sidste element i arrayet, så fjernes der bare den sidst oprettede bold.&lt;br /&gt;
&lt;br /&gt;
Hvis man var tilfreds med den opførsel, så kunne man blot fjerne kodelinjen med den anden append og kodelinjen med shorten. Så ville man have samme funktion.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
    if (balls[i].contains(mouseX, mouseY)) {&lt;br /&gt;
      balls = (Ball[]) append(balls, new Ball(balls[i].x, balls[i].y, random(-5, 5), random(-5, 5)));&lt;br /&gt;
      balls = (Ball[]) append(balls, new Ball(balls[i].x, balls[i].y, random(-5, 5), random(-5, 5)));&lt;br /&gt;
      balls = (Ball[]) shorten(balls);&lt;br /&gt;
      break;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Den nye bold der oprettes får bare en tilfældig retning, og den oprindelige bold fortsætter bare i den retning den var på vej i. Det er ikke den opførsel der ønskes i spillet. Der ønskes i stedet at det ser ud som om bolden &amp;quot;splittes op&amp;quot; i 2 bolde, og den opførsel laves ved at lade den oprindelige bold ændre 30 grader til den ene side, og den nye bold får 30 grader til den anden side.&lt;br /&gt;
&lt;br /&gt;
For at gøre dette, så oprettes der en metode multiply() i klassen Ball. Denne metode returnerer en ny bold af typen Ball, så nu kan koden i museklikket skrives som følger:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
    if (balls[i].contains(mouseX, mouseY)) {&lt;br /&gt;
      balls = (Ball[]) append(balls, balls[i].multiply());&lt;br /&gt;
      break;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Som det kan ses, så appendes der en ny bold ind i balls-arrayet, ud fra metoden multiply().&lt;br /&gt;
&lt;br /&gt;
Metoden multiply() oprettes inde i klassen med følgende kode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  Ball multiply() {&lt;br /&gt;
    xspeed *= xdirection;&lt;br /&gt;
    yspeed *= ydirection;&lt;br /&gt;
    xdirection = 1;&lt;br /&gt;
    ydirection = 1;&lt;br /&gt;
    float speed = dist(0, 0, xspeed, yspeed);&lt;br /&gt;
    float angle = acos(xspeed / speed);&lt;br /&gt;
    if (yspeed &amp;lt; 0) angle = 0.0 - angle;&lt;br /&gt;
    speed *= 1.5;&lt;br /&gt;
    xspeed = speed * cos(angle + PI / 6);&lt;br /&gt;
    yspeed = speed * sin(angle + PI / 6);&lt;br /&gt;
    Ball b = new Ball(x, y, speed * cos(angle - PI / 6), speed * sin(angle - PI / 6));&lt;br /&gt;
    return b;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Først regnes retningen over i xspeed og yspeed, så de kan være både positive og negative. På den måde indeholder de to variabler retningen.&lt;br /&gt;
&lt;br /&gt;
Dernæst omregnes x- og y-hastigheden til en samlet hastighed speed og en vinkel angle, som kan være mellem +PI og -PI (+/- 180 grader).&lt;br /&gt;
&lt;br /&gt;
Begge bolde skal bevæge sig hurtigere efter de er delt, så spillet gradvist bliver sværere, derfor ganges hastigheden med 1,5.&lt;br /&gt;
&lt;br /&gt;
Den oprindelige bold får nu en ny retning, ved at udregne x- og y-hastigheden ud fra den nye hastighed og vinklen plus 30 grader.&lt;br /&gt;
&lt;br /&gt;
Til sidst oprettes en ny bold med samme position som den oprindelige og en x- og y-hastighed udregnet fra den oprindelige bolds hastighed og vinklen minus 30 grader. Denne bold returneres fra metoden.&lt;br /&gt;
&lt;br /&gt;
==Refleksioner over anvendelsen==&lt;br /&gt;
Der er selvfølgelig stadig lang vej til man har et færdigt spil, men ideen var også at tage fat i, hvordan man anvender ChatGPT på en ordentlig og redelig måde i et programmeringsprojekt. Dette kan selvfølgelig altid gradbøjes, men hvis man håndterer anvendelsen som vist i eksemplet, så vil man ikke gøre noget der kommer i nærheden af plagiat.&lt;br /&gt;
&lt;br /&gt;
==Referencer== &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt; &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Programmering}}&lt;br /&gt;
&lt;br /&gt;
[[Kategori:Programmering teknik]]&lt;/div&gt;</summary>
		<author><name>Bar</name></author>
	</entry>
	<entry>
		<id>https://www.htxarduino.dk/index.php?title=Programmering_med_ChatGPT&amp;diff=5414</id>
		<title>Programmering med ChatGPT</title>
		<link rel="alternate" type="text/html" href="https://www.htxarduino.dk/index.php?title=Programmering_med_ChatGPT&amp;diff=5414"/>
		<updated>2024-04-30T10:48:53Z</updated>

		<summary type="html">&lt;p&gt;Bar: /* Den meget nemmere metode */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Det er ikke så svært at få ChatGPT&amp;lt;ref&amp;gt;[https://chat.openai.com/auth/login ChatGPT Login] - Indgangen til ChatGPT&amp;lt;/ref&amp;gt; til at lave kode, der skal man blot beskrive hvad man gerne vil have programmet til at gøre, og så kopiere den kode, der kommer ud af det - det giver tit ret gode resultater.&lt;br /&gt;
&lt;br /&gt;
Problemet med at anvende ChatGPT i forbindelse med skoleprojekter er, at man skal have forståelsen med i det, og at man ikke kan blive anklaget for plagiat.&lt;br /&gt;
&lt;br /&gt;
==Hvad må man ikke i et skoleprojekt==&lt;br /&gt;
*Man må ikke kopiere kode, som man ikke selv har skrevet, til et programmeringsprodukt uden at man angiver en kilde. Det er uanset hvor koden stammer fra, også selvom man har brugt ChatGPT til at &amp;quot;udvikle&amp;quot; koden.&lt;br /&gt;
*Man må ikke aflevere et produkt hvor de primære dele af koden er kopieret, heller ikke selvom man kildehenviser.&lt;br /&gt;
*Man må ikke få ChatGPT til at dokumentere sin kode, ved at man kopierer ChatGPT&#039;s beskrivelse ind i sin dokumentation af koden.&lt;br /&gt;
&lt;br /&gt;
De beskrevne eksempler er at betragte som plagiat, og vil blive håndteret efter skolens ordensregler, hvilket i værste fald kan ende med at et fag annulleres eller man bliver bortvist fra uddannelsen.&lt;br /&gt;
&lt;br /&gt;
==Hvad er tilladt med ChatGPT==&lt;br /&gt;
På samme måde som man må anvende kilder fra internettet, så må man i programmerings-faget i gymnasiet anvende ChatGPT i udviklingen af kode til et programmeringsprodukt. Dette er blevet tilladt via en revidering af vejledningen til faget&amp;lt;ref&amp;gt;[https://www.uvm.dk/-/media/filer/uvm/udd/gym/pdf23/aug/vejledninger/valgfag/230807-programmering-c--valgfag.pdf Vejledning] til Valgfaget Programmering C&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
I vejledningen står der som følger:&lt;br /&gt;
&lt;br /&gt;
: &#039;&#039;&amp;quot;brug af internettet er tilladt som fagligt hjælpemiddel ved de mundtlige prøver, inkluderer de tilladte hjælpemidler anvendelsen af chatbots og lignende på en måde, som afspejler, hvordan man arbejder i den daglige undervisning. Dette kunne fx være brug af ChatGPT til at debugge kode.&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Det skal altså afspejle den normale brug, som man også har ved at bruge internettet. Som angivet under hvad man ikke må, så er den normale brug, at man anvender information til at lære at programmere, men at man ikke tager så meget af sit produkt fra nettet, så man ikke har en forståelse af hvordan produktet er sammensat.&lt;br /&gt;
&lt;br /&gt;
Videre i vejledningen står der:&lt;br /&gt;
&lt;br /&gt;
: &#039;&#039;&amp;quot;I forhold til denne type hjælpemidler er det vigtigt at være opmærksom på, at den tilladte anvendelse er betinget af, at hjælpemidlerne kun benyttes i et omfang, hvor prøvebesvarelsen er selvstændig og udelukkende elevens egen.&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Igen understreges at det der afleveres skal være elevens selvstændigt udviklede produkt og dokumentation, hvor man på normal vis anvender internettet som et værktøj til at bibringe forståelse.&lt;br /&gt;
&lt;br /&gt;
==Problemet med ChatGPT==&lt;br /&gt;
Ligesom man ikke kan kilde-henvise til &amp;quot;google&amp;quot;, for at angive at man har fundet informationer på nettet, så kan man heller ikke kildehenvise til ChatGPT direkte som en kilde.&lt;br /&gt;
&lt;br /&gt;
Når man finder informationer med google&#039;, så skal man angive hvor på nettet man har fundet dem med så præcis en kildehenvisning, at man kan se den information der er blevet anvendt.&lt;br /&gt;
&lt;br /&gt;
Denne type henvisning kan man ikke lave i forhold til ChatGPT, da sprogmodellen der ligger bag ChatGPT konstant udvikler sig, samt at de svar sprogmodellen giver har et randomiseret element indbygget, som er med til at give bedre svar&amp;lt;ref&amp;gt;[https://www.it-vest.dk/arrangementer/sig-webinar-14-marts-2024-kunstig-intelligens-og-chatgpt-hvordan-virker-det-og-skal-vi-bare-opgive-undervisning-og-eksamen Webinar om kunstig intelligens]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Her er man altså nødt til at tage andre metoder i brug, for at kunne dokumentere at man har udviklet sit produkt ordentligt og redeligt.&lt;br /&gt;
&lt;br /&gt;
==Kildehenvisninger i dokumentation==&lt;br /&gt;
Der kan være forskellige standarder for hvordan man kildehenviser i forskellige uddannelser, dette er skrevet med udgangspunkt i at man anvender Word bibliografi-værktøj og her vist med en Harvard-lignende standard&amp;lt;ref&amp;gt;[https://holstebro-htx.dk/index.php/Word_Kildeliste Kildelister] anvendt i Microsoft Word&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Normal Internet-kilde til kode===&lt;br /&gt;
I dette eksempel er der angivet hvordan man ville dokumentere at man har anvendt kode fra et bibliotek til noget hardware på en [[Arduino]]. I det tænkte eksempel er det en 4 kanals AD-konverter&amp;lt;ref&amp;gt;[https://arduinotech.dk/shop/ads1115-module-4-channel-16-bit-i2c-adc-with-pro-gain-amplifier 4 kanals AD-konverter] fra ArduinoTech&amp;lt;/ref&amp;gt;, der er købt som modul.&lt;br /&gt;
&lt;br /&gt;
For at kunne anvende modulet i koden skal der kommunikeres med modulet på en måde, som er angivet i beskrivelsen af modulet - det er dog ikke nødvendigt at sætte sig ind i den grundlæggende kommunikation, hvis man blot ønsker at få værdier ind i sin software. Som en dokumentation for hvordan man anvender biblioteket kan man skrive følgende:&lt;br /&gt;
&lt;br /&gt;
====Eksempel på dokumentation====&lt;br /&gt;
Til at hente værdierne fra den 4 kanals AD-konverter anvendes et bibliotek fundet på GitHub (Singh, 2018) som kan indlæse de analoge spændinger.&lt;br /&gt;
Til at sætte AD-konverteren rigtigt op, til at kunne læse 4 spændinger, så anvendes eksemplet ”ADS1115_SingleEnded.ino” og i setup skrives følgende kode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
    ads.getAddr_ADS1115(ADS1115_DEFAULT_ADDRESS);   // 0x48, 1001 000 (ADDR = GND)&lt;br /&gt;
    ads.setGain(GAIN_TWO);          // 2x gain   +/- 2.048V  1 bit = 0.0625mV (default)&lt;br /&gt;
    ads.setMode(MODE_CONTIN);       // Continuous conversion mode&lt;br /&gt;
    ads.setRate(RATE_128);          // 128SPS (default)&lt;br /&gt;
    ads.setOSMode(OSMODE_SINGLE);   // Set to start a single-conversion&lt;br /&gt;
    ads.begin();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
I [[loop()]] testes i første omgang, om det kan lade sig gøre at læse de 4 kanaler. Dette gøres ved at afvikle følgende testkode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
    address = ads.ads_i2cAddress;&lt;br /&gt;
    Wire.beginTransmission(address);&lt;br /&gt;
    error = Wire.endTransmission();&lt;br /&gt;
    if (error == 0)&lt;br /&gt;
    {&lt;br /&gt;
        int16_t adc0, adc1, adc2, adc3;&lt;br /&gt;
&lt;br /&gt;
        adc0 = ads.Measure_SingleEnded(0);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 1: &amp;quot;);&lt;br /&gt;
        Serial.println(adc0);&lt;br /&gt;
        adc1 = ads.Measure_SingleEnded(1);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 2: &amp;quot;);&lt;br /&gt;
        Serial.println(adc1);&lt;br /&gt;
        adc2 = ads.Measure_SingleEnded(2);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 3: &amp;quot;);&lt;br /&gt;
        Serial.println(adc2);&lt;br /&gt;
        adc3 = ads.Measure_SingleEnded(3);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 4: &amp;quot;);&lt;br /&gt;
        Serial.println(adc3);&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Denne test giver det ønskede resultat.&lt;br /&gt;
&lt;br /&gt;
Ud fra denne beskrivelse viser man, at man tager andres kode, og anvender ind i sit eget projekt, og man angiver præcist i sin beskrivelse hvad man har taget fra andres kode.&lt;br /&gt;
&lt;br /&gt;
I kildelisten vil kilden optræde på følgende måde:&lt;br /&gt;
&lt;br /&gt;
: Singh, Y., 2018. Arduino Library ADS1115 16 bit 4 channel ADC. [Online] &amp;lt;br /&amp;gt;&lt;br /&gt;
: Available at: https://github.com/ncdcommunity/Arduino_Library_ADS1115_16Bit_4Channel_ADC&amp;lt;br /&amp;gt;&lt;br /&gt;
: [Senest hentet eller vist den 15 marts 2024].&lt;br /&gt;
&lt;br /&gt;
===ChatGPT som kilde til kode===&lt;br /&gt;
Det følgende er skrevet med udgangspunkt i det der er beskrevet på viden.ai&amp;lt;ref&amp;gt;[https://viden.ai/korrekt-kildehenvisning-af-chatgpt/ Korrekt kildehenvisning af ChatGPT]&amp;lt;/ref&amp;gt;. hvor der angives hvordan man kildehenviser, men også lidt om hvordan man håndterer det i tekst - i korte træk, lav et metodeafsnit, beskriv hvad man gør og vær meget redelig, ved at man angiver hvad man har fået af ChatGPT ved at lægge det ved som et bilag.&lt;br /&gt;
&lt;br /&gt;
Hvis man forstår at prompte fornuftigt, så er ChatGPT faktisk ret god til at foreslå kode, der kan anvendes, men ligesom det er plagiat hvis man kopierer fra nettet, så er det plagiat, hvis man lader ChatGPT skrive store dele af ens program for sig.&lt;br /&gt;
&lt;br /&gt;
Som det er formuleret i vejledningen til både programmering C og B, så kan man anvende ChatGPT til hjælp i fejlfinding af kode. For at kunne kildehenvise korrekt til hjælp med fejlfinding, så skal man angive hvad man har promptet til ChatGPT og hvad den har svaret - det kan placeres i bilag.&lt;br /&gt;
&lt;br /&gt;
En anden ting, som også er OK at få hjælp med er, at komme i gang med programmet - det er denne problematik der her gives et eksempel på. I eksemplet beskrives hvad man skal skrive i sin dokumentation, når man har anvendt denne hjælp, og der er forslag til hvordan man kommer videre i projektet.&lt;br /&gt;
&lt;br /&gt;
Konkret er det starten på udviklingen af et lille spil med bolde i et vindue, udviklet i Processing, der tages udgangspunkt i.&lt;br /&gt;
&lt;br /&gt;
====Metodeafsnit med omtale af ChatGPT====&lt;br /&gt;
Når man anvender CharGPT, så skal man dokumentere hvordan man har gjort det, og hvilke overvejelser der ligger bag det. Det betegnes i rapportskrivning som et metodeafsnit. Det kunne i dette eksempel lyde:&lt;br /&gt;
&lt;br /&gt;
For at få en fornuftig start på programkoden er der brugt ChatGPT til at få rammerne på koden etableret, og til at få et system, så der kan optræde flere bolde i programvinduet. Det er ChatGPT 3.5 (OpenAI, 2023)&amp;lt;ref&amp;gt;[https://chat.openai.com/chat Indgangen til ChatGPT 3.5]&amp;lt;/ref&amp;gt; der er anvendt til denne hjælp. Til programstarten blev der promptet efter at få et programvindue på 800x600 hvor en bold bevæger sig rundt. Den foreslåede kode blev kopieret ind i processings IDE (Processing, 2024)&amp;lt;ref&amp;gt;[https://processing.org Hovedsiden for Processing]&amp;lt;/ref&amp;gt; og testet – den opførte sig som forventet.&lt;br /&gt;
&lt;br /&gt;
Derefter blev der promptet efter at få den bold der bevægede sig til at dele sig op i to, når man klikker på den med musen. Dette resulterede i en væsentligt anderledes kode, som igen blev kopieret ind i processing og testet, og igen med et acceptabelt resultat. Dialogen med ChatGPT (OpenAI, 2023) og herunder de to koder, kan ses i bilag 1.&lt;br /&gt;
&lt;br /&gt;
Herefter er resten af koden udviklet på traditionel vis, hvor første trin var at dokumentere princippet i den foreslåede kode, specielt den Ball klasse der blev introduceret for at kunne arbejde med flere bolde i vinduet.&lt;br /&gt;
&lt;br /&gt;
Det nævnte bilag 1 [[media:ChatGPT-dialog-1.pdf|kan ses i denne PDF]].&lt;br /&gt;
&lt;br /&gt;
Når man opretter kilden i Word, så er det lidt forskelligt hvilke felter der er synlige, alt efter hvilken standard man har aktiv - men ved Harvard-Anglia standarden kan indtastningerne se således ud:&lt;br /&gt;
&lt;br /&gt;
[[fil:citat-ChatGPT.png|Indtastningerne ved kildehenvisning til ChatGPT|600px]]&amp;lt;br /&amp;gt;&#039;&#039;Indtastningerne ved kildehenvisning til ChatGPT&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Mere om teknikken i at anvende kildelister kan ses på [https://holstebro-htx.dk/index.php/Word_Kildeliste Holstebro HTX Wiki - Kildelister].&lt;br /&gt;
&lt;br /&gt;
====Den meget nemmere metode====&lt;br /&gt;
Tingene udvikler sig hele tiden, og nu kan man faktisk få et link til den dialog man har haft med ChatGPT 3.5.&lt;br /&gt;
&lt;br /&gt;
Måden man gør det på er, at man klikker på en ikon i øverste højre side af websiden med den dialog man gerne vil linke til, som vist herunder, hvor man kommer i en dialog, så man kan kopiere linket.&amp;lt;br /&amp;gt;&lt;br /&gt;
[[fil:link_til_chatGPT.png|Link ikon til dialog i chatGPT]]&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Link ikon til dialog i chatGPT&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Selve linket ser ud som følger: https://chat.openai.com/share/90e9607f-bff9-40d1-a68c-9617051e9615.&lt;br /&gt;
&lt;br /&gt;
====Dokumentation af koden udviklet af ChatGPT====&lt;br /&gt;
Da der skulle kunne dannes nye bolde så oprettes der en klasse, som ChatGPT skriver det i dialogen i Bilag 1:&lt;br /&gt;
&lt;br /&gt;
: &#039;&#039;&amp;quot;Dette kodeeksempel opretter en klasse kaldet Ball, som repræsenterer boldobjekterne. Når musen klikkes, kontrolleres det, om musens position er inden for en bold. Hvis det er tilfældet, oprettes to nye boldobjekter, der bevæger sig i forskellige retninger, og den originale bold fjernes fra arrayet.&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Ved at teste koden kan man se at det ikke er det helt rigtige den formulerer - der oprettes godt nok to nye bold-objekter, men det er ikke den oprindelige bold der fjernes, det er den ene af de ny-oprettede bolde. Det kan ses ved at de to bolde kommer i samme position, og den ene fortsætter i samme retning (den oprindelige), mens den ny-oprettede går i en tilfældig retning. Dette rettes til senere i dokumentationen under &amp;quot;oprettelse af ny bold&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
For at have en god struktur i koden, så placeres klassen Ball i en fil for sig kaldet Ball. Denne fil starter med at definere koden som en klasse med linjen:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
class Ball {&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dernæst defineres klassens egenskaber, der er boldens position og hastighed samt en fast diameter. Ud over det er der en x- og y-retning defineret. Den anvendes til at sige om bolden bevæger sig i en positiv eller negativ retning, så de skifter mellem +1 og -1, når kanterne rammes.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  float x, y;&lt;br /&gt;
  float xspeed, yspeed;&lt;br /&gt;
  int diameter = 30;&lt;br /&gt;
  int xdirection = 1;&lt;br /&gt;
  int ydirection = 1;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der defineres to forskellige constructors til bolden. Den første anvendes til at danne den første bold med, hvor position og hastighed sættes tilfældigt.&lt;br /&gt;
&lt;br /&gt;
Her forudses et problem at der kan komme et randfænomen, hvis bolden dannes, så den ligger med noget uden for skærmen. Da det er tilfældigt; så er det sjældent problemet opstår. For at fremprovokere det oftere er det testet med en diameter på 200, hvor det kunne ses at bolden bliver &amp;quot;hængende&amp;quot; i kanten.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  Ball() {&lt;br /&gt;
    x = random(width);&lt;br /&gt;
    y = random(height);&lt;br /&gt;
    xspeed = random(0.5, 2);&lt;br /&gt;
    yspeed = random(0.5, 2);&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Dette rettes ved at omskrive den foreslåede constructor til følgende kode, hvor bolden placeres mindst en halv diameter fra kanten:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  Ball() {&lt;br /&gt;
    x = random(diameter / 2, width - diameter / 2);&lt;br /&gt;
    y = random(diameter / 2, height - diameter / 2);&lt;br /&gt;
    xspeed = random(0.5, 2);&lt;br /&gt;
    yspeed = random(0.5, 2);&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Den anden constructor tager fire parametre, der er positionen og hastigheden. Denne constructor anvendes, når der skal dannes nye bolde, hvor koden netop skal starte den nye bold i den oprindelige bolds position, og med en ny retning.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  Ball(float x, float y, float xspeed, float yspeed) {&lt;br /&gt;
    this.x = x;&lt;br /&gt;
    this.y = y;&lt;br /&gt;
    this.xspeed = xspeed;&lt;br /&gt;
    this.yspeed = yspeed;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ud over disse standard ting til oprettelsen af objekter, så er der 3 metoder i klassen. Den første er en move() metode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  void move() {&lt;br /&gt;
    x = x + (xspeed * xdirection);&lt;br /&gt;
    y = y + (yspeed * ydirection);&lt;br /&gt;
&lt;br /&gt;
    if ((x + diameter/2 &amp;gt;= width) || (x - diameter/2 &amp;lt;= 0)) {&lt;br /&gt;
      xdirection *= -1;&lt;br /&gt;
    }&lt;br /&gt;
    if ((y + diameter/2 &amp;gt;= height) || (y - diameter/2 &amp;lt;= 0)) {&lt;br /&gt;
      ydirection *= -1;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Måden metoden virker på er at den lægger hastigheden til boldens position (både x og y), og hvis boldens position (både i x og y) er kommet uden for rammen, så ændres retningen for enten x eller y.&lt;br /&gt;
&lt;br /&gt;
For at kunne vise bolden er der en display() metode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  void display() {&lt;br /&gt;
    ellipse(x, y, diameter, diameter);&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Den sidste metode hedder contains(), og den tager en position som parameter til metoden. Der undersøges så om den position ligger inden for bolden ved at se om afstanden mellem boldens center og den testede position er mindre end den halve diameter. Hvis den er inden for bolden, så returneres true, ellers returneres false:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  boolean contains(float x, float y) {&lt;br /&gt;
    float d = dist(x, y, this.x, this.y);&lt;br /&gt;
    if (d &amp;lt; diameter/2) {&lt;br /&gt;
      return true;&lt;br /&gt;
    } else {&lt;br /&gt;
      return false;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Oprettelse af ny bold====&lt;br /&gt;
I den oprindelige kode undersøges om der er klikket på en bold, ved at alle bolde løbes igennem i mousePressed() funktionen, og med metoden contains undersøges om der er klikket på en bold. Denne måde at undersøge alle bolde på beholdes.&lt;br /&gt;
&lt;br /&gt;
Som omtalt er det ikke den smarteste måde til at dele bolden op i to, der anvendes. Som det ses i koden herunder, så appendes der to nye bolde på med den oprindelige bolds x- og y-position på samt tilfældige x- og y-hastigheder. Disse to bolde lægges i slutningen af arrayet. Derefter anvendes shorten&amp;lt;ref&amp;gt;[https://processing.org/reference/shorten_.html Processings shorten metode til arrays]&amp;lt;/ref&amp;gt; til at fjerne et element, men da det element der fjernes er det sidste element i arrayet, så fjernes der bare den sidst oprettede bold.&lt;br /&gt;
&lt;br /&gt;
Hvis man var tilfreds med den opførsel, så kunne man blot fjerne kodelinjen med den anden append og kodelinjen med shorten. Så ville man have samme funktion.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
    if (balls[i].contains(mouseX, mouseY)) {&lt;br /&gt;
      balls = (Ball[]) append(balls, new Ball(balls[i].x, balls[i].y, random(-5, 5), random(-5, 5)));&lt;br /&gt;
      balls = (Ball[]) append(balls, new Ball(balls[i].x, balls[i].y, random(-5, 5), random(-5, 5)));&lt;br /&gt;
      balls = (Ball[]) shorten(balls);&lt;br /&gt;
      break;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Den nye bold der oprettes får bare en tilfældig retning, og den oprindelige bold fortsætter bare i den retning den var på vej i. Det er ikke den opførsel der ønskes i spillet. Der ønskes i stedet at det ser ud som om bolden &amp;quot;splittes op&amp;quot; i 2 bolde, og den opførsel laves ved at lade den oprindelige bold ændre 30 grader til den ene side, og den nye bold får 30 grader til den anden side.&lt;br /&gt;
&lt;br /&gt;
For at gøre dette, så oprettes der en metode multiply() i klassen Ball. Denne metode returnerer en ny bold af typen Ball, så nu kan koden i museklikket skrives som følger:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
    if (balls[i].contains(mouseX, mouseY)) {&lt;br /&gt;
      balls = (Ball[]) append(balls, balls[i].multiply());&lt;br /&gt;
      break;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Som det kan ses, så appendes der en ny bold ind i balls-arrayet, ud fra metoden multiply().&lt;br /&gt;
&lt;br /&gt;
Metoden multiply() oprettes inde i klassen med følgende kode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  Ball multiply() {&lt;br /&gt;
    xspeed *= xdirection;&lt;br /&gt;
    yspeed *= ydirection;&lt;br /&gt;
    xdirection = 1;&lt;br /&gt;
    ydirection = 1;&lt;br /&gt;
    float speed = dist(0, 0, xspeed, yspeed);&lt;br /&gt;
    float angle = acos(xspeed / speed);&lt;br /&gt;
    if (yspeed &amp;lt; 0) angle = 0.0 - angle;&lt;br /&gt;
    speed *= 1.5;&lt;br /&gt;
    xspeed = speed * cos(angle + PI / 6);&lt;br /&gt;
    yspeed = speed * sin(angle + PI / 6);&lt;br /&gt;
    Ball b = new Ball(x, y, speed * cos(angle - PI / 6), speed * sin(angle - PI / 6));&lt;br /&gt;
    return b;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Først regnes retningen over i xspeed og yspeed, så de kan være både positive og negative. På den måde indeholder de to variabler retningen.&lt;br /&gt;
&lt;br /&gt;
Dernæst omregnes x- og y-hastigheden til en samlet hastighed speed og en vinkel angle, som kan være mellem +PI og -PI (+/- 180 grader).&lt;br /&gt;
&lt;br /&gt;
Begge bolde skal bevæge sig hurtigere efter de er delt, så spillet gradvist bliver sværere, derfor ganges hastigheden med 1,5.&lt;br /&gt;
&lt;br /&gt;
Den oprindelige bold får nu en ny retning, ved at udregne x- og y-hastigheden ud fra den nye hastighed og vinklen plus 30 grader.&lt;br /&gt;
&lt;br /&gt;
Til sidst oprettes en ny bold med samme position som den oprindelige og en x- og y-hastighed udregnet fra den oprindelige bolds hastighed og vinklen minus 30 grader. Denne bold returneres fra metoden.&lt;br /&gt;
&lt;br /&gt;
==Refleksioner over anvendelsen==&lt;br /&gt;
Der er selvfølgelig stadig lang vej til man har et færdigt spil, men ideen var også at tage fat i, hvordan man anvender ChatGPT på en ordentlig og redelig måde i et programmeringsprojekt. Dette kan selvfølgelig altid gradbøjes, men hvis man håndterer anvendelsen som vist i eksemplet, så vil man ikke gøre noget der kommer i nærheden af plagiat.&lt;br /&gt;
&lt;br /&gt;
==Referencer== &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt; &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Programmering}}&lt;br /&gt;
&lt;br /&gt;
[[Kategori:Programmering teknik]]&lt;/div&gt;</summary>
		<author><name>Bar</name></author>
	</entry>
	<entry>
		<id>https://www.htxarduino.dk/index.php?title=Fil:Link_til_chatGPT.png&amp;diff=5413</id>
		<title>Fil:Link til chatGPT.png</title>
		<link rel="alternate" type="text/html" href="https://www.htxarduino.dk/index.php?title=Fil:Link_til_chatGPT.png&amp;diff=5413"/>
		<updated>2024-04-30T10:48:20Z</updated>

		<summary type="html">&lt;p&gt;Bar: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Bar</name></author>
	</entry>
	<entry>
		<id>https://www.htxarduino.dk/index.php?title=Programmering_med_ChatGPT&amp;diff=5412</id>
		<title>Programmering med ChatGPT</title>
		<link rel="alternate" type="text/html" href="https://www.htxarduino.dk/index.php?title=Programmering_med_ChatGPT&amp;diff=5412"/>
		<updated>2024-04-30T10:47:45Z</updated>

		<summary type="html">&lt;p&gt;Bar: /* Den meget nemmere metode */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Det er ikke så svært at få ChatGPT&amp;lt;ref&amp;gt;[https://chat.openai.com/auth/login ChatGPT Login] - Indgangen til ChatGPT&amp;lt;/ref&amp;gt; til at lave kode, der skal man blot beskrive hvad man gerne vil have programmet til at gøre, og så kopiere den kode, der kommer ud af det - det giver tit ret gode resultater.&lt;br /&gt;
&lt;br /&gt;
Problemet med at anvende ChatGPT i forbindelse med skoleprojekter er, at man skal have forståelsen med i det, og at man ikke kan blive anklaget for plagiat.&lt;br /&gt;
&lt;br /&gt;
==Hvad må man ikke i et skoleprojekt==&lt;br /&gt;
*Man må ikke kopiere kode, som man ikke selv har skrevet, til et programmeringsprodukt uden at man angiver en kilde. Det er uanset hvor koden stammer fra, også selvom man har brugt ChatGPT til at &amp;quot;udvikle&amp;quot; koden.&lt;br /&gt;
*Man må ikke aflevere et produkt hvor de primære dele af koden er kopieret, heller ikke selvom man kildehenviser.&lt;br /&gt;
*Man må ikke få ChatGPT til at dokumentere sin kode, ved at man kopierer ChatGPT&#039;s beskrivelse ind i sin dokumentation af koden.&lt;br /&gt;
&lt;br /&gt;
De beskrevne eksempler er at betragte som plagiat, og vil blive håndteret efter skolens ordensregler, hvilket i værste fald kan ende med at et fag annulleres eller man bliver bortvist fra uddannelsen.&lt;br /&gt;
&lt;br /&gt;
==Hvad er tilladt med ChatGPT==&lt;br /&gt;
På samme måde som man må anvende kilder fra internettet, så må man i programmerings-faget i gymnasiet anvende ChatGPT i udviklingen af kode til et programmeringsprodukt. Dette er blevet tilladt via en revidering af vejledningen til faget&amp;lt;ref&amp;gt;[https://www.uvm.dk/-/media/filer/uvm/udd/gym/pdf23/aug/vejledninger/valgfag/230807-programmering-c--valgfag.pdf Vejledning] til Valgfaget Programmering C&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
I vejledningen står der som følger:&lt;br /&gt;
&lt;br /&gt;
: &#039;&#039;&amp;quot;brug af internettet er tilladt som fagligt hjælpemiddel ved de mundtlige prøver, inkluderer de tilladte hjælpemidler anvendelsen af chatbots og lignende på en måde, som afspejler, hvordan man arbejder i den daglige undervisning. Dette kunne fx være brug af ChatGPT til at debugge kode.&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Det skal altså afspejle den normale brug, som man også har ved at bruge internettet. Som angivet under hvad man ikke må, så er den normale brug, at man anvender information til at lære at programmere, men at man ikke tager så meget af sit produkt fra nettet, så man ikke har en forståelse af hvordan produktet er sammensat.&lt;br /&gt;
&lt;br /&gt;
Videre i vejledningen står der:&lt;br /&gt;
&lt;br /&gt;
: &#039;&#039;&amp;quot;I forhold til denne type hjælpemidler er det vigtigt at være opmærksom på, at den tilladte anvendelse er betinget af, at hjælpemidlerne kun benyttes i et omfang, hvor prøvebesvarelsen er selvstændig og udelukkende elevens egen.&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Igen understreges at det der afleveres skal være elevens selvstændigt udviklede produkt og dokumentation, hvor man på normal vis anvender internettet som et værktøj til at bibringe forståelse.&lt;br /&gt;
&lt;br /&gt;
==Problemet med ChatGPT==&lt;br /&gt;
Ligesom man ikke kan kilde-henvise til &amp;quot;google&amp;quot;, for at angive at man har fundet informationer på nettet, så kan man heller ikke kildehenvise til ChatGPT direkte som en kilde.&lt;br /&gt;
&lt;br /&gt;
Når man finder informationer med google&#039;, så skal man angive hvor på nettet man har fundet dem med så præcis en kildehenvisning, at man kan se den information der er blevet anvendt.&lt;br /&gt;
&lt;br /&gt;
Denne type henvisning kan man ikke lave i forhold til ChatGPT, da sprogmodellen der ligger bag ChatGPT konstant udvikler sig, samt at de svar sprogmodellen giver har et randomiseret element indbygget, som er med til at give bedre svar&amp;lt;ref&amp;gt;[https://www.it-vest.dk/arrangementer/sig-webinar-14-marts-2024-kunstig-intelligens-og-chatgpt-hvordan-virker-det-og-skal-vi-bare-opgive-undervisning-og-eksamen Webinar om kunstig intelligens]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Her er man altså nødt til at tage andre metoder i brug, for at kunne dokumentere at man har udviklet sit produkt ordentligt og redeligt.&lt;br /&gt;
&lt;br /&gt;
==Kildehenvisninger i dokumentation==&lt;br /&gt;
Der kan være forskellige standarder for hvordan man kildehenviser i forskellige uddannelser, dette er skrevet med udgangspunkt i at man anvender Word bibliografi-værktøj og her vist med en Harvard-lignende standard&amp;lt;ref&amp;gt;[https://holstebro-htx.dk/index.php/Word_Kildeliste Kildelister] anvendt i Microsoft Word&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Normal Internet-kilde til kode===&lt;br /&gt;
I dette eksempel er der angivet hvordan man ville dokumentere at man har anvendt kode fra et bibliotek til noget hardware på en [[Arduino]]. I det tænkte eksempel er det en 4 kanals AD-konverter&amp;lt;ref&amp;gt;[https://arduinotech.dk/shop/ads1115-module-4-channel-16-bit-i2c-adc-with-pro-gain-amplifier 4 kanals AD-konverter] fra ArduinoTech&amp;lt;/ref&amp;gt;, der er købt som modul.&lt;br /&gt;
&lt;br /&gt;
For at kunne anvende modulet i koden skal der kommunikeres med modulet på en måde, som er angivet i beskrivelsen af modulet - det er dog ikke nødvendigt at sætte sig ind i den grundlæggende kommunikation, hvis man blot ønsker at få værdier ind i sin software. Som en dokumentation for hvordan man anvender biblioteket kan man skrive følgende:&lt;br /&gt;
&lt;br /&gt;
====Eksempel på dokumentation====&lt;br /&gt;
Til at hente værdierne fra den 4 kanals AD-konverter anvendes et bibliotek fundet på GitHub (Singh, 2018) som kan indlæse de analoge spændinger.&lt;br /&gt;
Til at sætte AD-konverteren rigtigt op, til at kunne læse 4 spændinger, så anvendes eksemplet ”ADS1115_SingleEnded.ino” og i setup skrives følgende kode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
    ads.getAddr_ADS1115(ADS1115_DEFAULT_ADDRESS);   // 0x48, 1001 000 (ADDR = GND)&lt;br /&gt;
    ads.setGain(GAIN_TWO);          // 2x gain   +/- 2.048V  1 bit = 0.0625mV (default)&lt;br /&gt;
    ads.setMode(MODE_CONTIN);       // Continuous conversion mode&lt;br /&gt;
    ads.setRate(RATE_128);          // 128SPS (default)&lt;br /&gt;
    ads.setOSMode(OSMODE_SINGLE);   // Set to start a single-conversion&lt;br /&gt;
    ads.begin();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
I [[loop()]] testes i første omgang, om det kan lade sig gøre at læse de 4 kanaler. Dette gøres ved at afvikle følgende testkode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
    address = ads.ads_i2cAddress;&lt;br /&gt;
    Wire.beginTransmission(address);&lt;br /&gt;
    error = Wire.endTransmission();&lt;br /&gt;
    if (error == 0)&lt;br /&gt;
    {&lt;br /&gt;
        int16_t adc0, adc1, adc2, adc3;&lt;br /&gt;
&lt;br /&gt;
        adc0 = ads.Measure_SingleEnded(0);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 1: &amp;quot;);&lt;br /&gt;
        Serial.println(adc0);&lt;br /&gt;
        adc1 = ads.Measure_SingleEnded(1);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 2: &amp;quot;);&lt;br /&gt;
        Serial.println(adc1);&lt;br /&gt;
        adc2 = ads.Measure_SingleEnded(2);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 3: &amp;quot;);&lt;br /&gt;
        Serial.println(adc2);&lt;br /&gt;
        adc3 = ads.Measure_SingleEnded(3);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 4: &amp;quot;);&lt;br /&gt;
        Serial.println(adc3);&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Denne test giver det ønskede resultat.&lt;br /&gt;
&lt;br /&gt;
Ud fra denne beskrivelse viser man, at man tager andres kode, og anvender ind i sit eget projekt, og man angiver præcist i sin beskrivelse hvad man har taget fra andres kode.&lt;br /&gt;
&lt;br /&gt;
I kildelisten vil kilden optræde på følgende måde:&lt;br /&gt;
&lt;br /&gt;
: Singh, Y., 2018. Arduino Library ADS1115 16 bit 4 channel ADC. [Online] &amp;lt;br /&amp;gt;&lt;br /&gt;
: Available at: https://github.com/ncdcommunity/Arduino_Library_ADS1115_16Bit_4Channel_ADC&amp;lt;br /&amp;gt;&lt;br /&gt;
: [Senest hentet eller vist den 15 marts 2024].&lt;br /&gt;
&lt;br /&gt;
===ChatGPT som kilde til kode===&lt;br /&gt;
Det følgende er skrevet med udgangspunkt i det der er beskrevet på viden.ai&amp;lt;ref&amp;gt;[https://viden.ai/korrekt-kildehenvisning-af-chatgpt/ Korrekt kildehenvisning af ChatGPT]&amp;lt;/ref&amp;gt;. hvor der angives hvordan man kildehenviser, men også lidt om hvordan man håndterer det i tekst - i korte træk, lav et metodeafsnit, beskriv hvad man gør og vær meget redelig, ved at man angiver hvad man har fået af ChatGPT ved at lægge det ved som et bilag.&lt;br /&gt;
&lt;br /&gt;
Hvis man forstår at prompte fornuftigt, så er ChatGPT faktisk ret god til at foreslå kode, der kan anvendes, men ligesom det er plagiat hvis man kopierer fra nettet, så er det plagiat, hvis man lader ChatGPT skrive store dele af ens program for sig.&lt;br /&gt;
&lt;br /&gt;
Som det er formuleret i vejledningen til både programmering C og B, så kan man anvende ChatGPT til hjælp i fejlfinding af kode. For at kunne kildehenvise korrekt til hjælp med fejlfinding, så skal man angive hvad man har promptet til ChatGPT og hvad den har svaret - det kan placeres i bilag.&lt;br /&gt;
&lt;br /&gt;
En anden ting, som også er OK at få hjælp med er, at komme i gang med programmet - det er denne problematik der her gives et eksempel på. I eksemplet beskrives hvad man skal skrive i sin dokumentation, når man har anvendt denne hjælp, og der er forslag til hvordan man kommer videre i projektet.&lt;br /&gt;
&lt;br /&gt;
Konkret er det starten på udviklingen af et lille spil med bolde i et vindue, udviklet i Processing, der tages udgangspunkt i.&lt;br /&gt;
&lt;br /&gt;
====Metodeafsnit med omtale af ChatGPT====&lt;br /&gt;
Når man anvender CharGPT, så skal man dokumentere hvordan man har gjort det, og hvilke overvejelser der ligger bag det. Det betegnes i rapportskrivning som et metodeafsnit. Det kunne i dette eksempel lyde:&lt;br /&gt;
&lt;br /&gt;
For at få en fornuftig start på programkoden er der brugt ChatGPT til at få rammerne på koden etableret, og til at få et system, så der kan optræde flere bolde i programvinduet. Det er ChatGPT 3.5 (OpenAI, 2023)&amp;lt;ref&amp;gt;[https://chat.openai.com/chat Indgangen til ChatGPT 3.5]&amp;lt;/ref&amp;gt; der er anvendt til denne hjælp. Til programstarten blev der promptet efter at få et programvindue på 800x600 hvor en bold bevæger sig rundt. Den foreslåede kode blev kopieret ind i processings IDE (Processing, 2024)&amp;lt;ref&amp;gt;[https://processing.org Hovedsiden for Processing]&amp;lt;/ref&amp;gt; og testet – den opførte sig som forventet.&lt;br /&gt;
&lt;br /&gt;
Derefter blev der promptet efter at få den bold der bevægede sig til at dele sig op i to, når man klikker på den med musen. Dette resulterede i en væsentligt anderledes kode, som igen blev kopieret ind i processing og testet, og igen med et acceptabelt resultat. Dialogen med ChatGPT (OpenAI, 2023) og herunder de to koder, kan ses i bilag 1.&lt;br /&gt;
&lt;br /&gt;
Herefter er resten af koden udviklet på traditionel vis, hvor første trin var at dokumentere princippet i den foreslåede kode, specielt den Ball klasse der blev introduceret for at kunne arbejde med flere bolde i vinduet.&lt;br /&gt;
&lt;br /&gt;
Det nævnte bilag 1 [[media:ChatGPT-dialog-1.pdf|kan ses i denne PDF]].&lt;br /&gt;
&lt;br /&gt;
Når man opretter kilden i Word, så er det lidt forskelligt hvilke felter der er synlige, alt efter hvilken standard man har aktiv - men ved Harvard-Anglia standarden kan indtastningerne se således ud:&lt;br /&gt;
&lt;br /&gt;
[[fil:citat-ChatGPT.png|Indtastningerne ved kildehenvisning til ChatGPT|600px]]&amp;lt;br /&amp;gt;&#039;&#039;Indtastningerne ved kildehenvisning til ChatGPT&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Mere om teknikken i at anvende kildelister kan ses på [https://holstebro-htx.dk/index.php/Word_Kildeliste Holstebro HTX Wiki - Kildelister].&lt;br /&gt;
&lt;br /&gt;
====Den meget nemmere metode====&lt;br /&gt;
Tingene udvikler sig hele tiden, og nu kan man faktisk få et link til den dialog man har haft med ChatGPT 3.5.&lt;br /&gt;
&lt;br /&gt;
Måden man gør det på er, at man klikker på en ikon i øverste højre side af websiden med den dialog man gerne vil linke til, som vist herunder, hvor man kommer i en dialog, så man kan kopiere linket.&amp;lt;br /&amp;gt;&lt;br /&gt;
[[fil:link_til_chatGPT.png|Link ikon til dialog i chatGPT]]&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Link ikon til dialog i chatGPT&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Selve linket ser ud som følger: [https://chat.openai.com/share/90e9607f-bff9-40d1-a68c-9617051e9615].&lt;br /&gt;
&lt;br /&gt;
====Dokumentation af koden udviklet af ChatGPT====&lt;br /&gt;
Da der skulle kunne dannes nye bolde så oprettes der en klasse, som ChatGPT skriver det i dialogen i Bilag 1:&lt;br /&gt;
&lt;br /&gt;
: &#039;&#039;&amp;quot;Dette kodeeksempel opretter en klasse kaldet Ball, som repræsenterer boldobjekterne. Når musen klikkes, kontrolleres det, om musens position er inden for en bold. Hvis det er tilfældet, oprettes to nye boldobjekter, der bevæger sig i forskellige retninger, og den originale bold fjernes fra arrayet.&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Ved at teste koden kan man se at det ikke er det helt rigtige den formulerer - der oprettes godt nok to nye bold-objekter, men det er ikke den oprindelige bold der fjernes, det er den ene af de ny-oprettede bolde. Det kan ses ved at de to bolde kommer i samme position, og den ene fortsætter i samme retning (den oprindelige), mens den ny-oprettede går i en tilfældig retning. Dette rettes til senere i dokumentationen under &amp;quot;oprettelse af ny bold&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
For at have en god struktur i koden, så placeres klassen Ball i en fil for sig kaldet Ball. Denne fil starter med at definere koden som en klasse med linjen:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
class Ball {&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dernæst defineres klassens egenskaber, der er boldens position og hastighed samt en fast diameter. Ud over det er der en x- og y-retning defineret. Den anvendes til at sige om bolden bevæger sig i en positiv eller negativ retning, så de skifter mellem +1 og -1, når kanterne rammes.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  float x, y;&lt;br /&gt;
  float xspeed, yspeed;&lt;br /&gt;
  int diameter = 30;&lt;br /&gt;
  int xdirection = 1;&lt;br /&gt;
  int ydirection = 1;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der defineres to forskellige constructors til bolden. Den første anvendes til at danne den første bold med, hvor position og hastighed sættes tilfældigt.&lt;br /&gt;
&lt;br /&gt;
Her forudses et problem at der kan komme et randfænomen, hvis bolden dannes, så den ligger med noget uden for skærmen. Da det er tilfældigt; så er det sjældent problemet opstår. For at fremprovokere det oftere er det testet med en diameter på 200, hvor det kunne ses at bolden bliver &amp;quot;hængende&amp;quot; i kanten.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  Ball() {&lt;br /&gt;
    x = random(width);&lt;br /&gt;
    y = random(height);&lt;br /&gt;
    xspeed = random(0.5, 2);&lt;br /&gt;
    yspeed = random(0.5, 2);&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Dette rettes ved at omskrive den foreslåede constructor til følgende kode, hvor bolden placeres mindst en halv diameter fra kanten:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  Ball() {&lt;br /&gt;
    x = random(diameter / 2, width - diameter / 2);&lt;br /&gt;
    y = random(diameter / 2, height - diameter / 2);&lt;br /&gt;
    xspeed = random(0.5, 2);&lt;br /&gt;
    yspeed = random(0.5, 2);&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Den anden constructor tager fire parametre, der er positionen og hastigheden. Denne constructor anvendes, når der skal dannes nye bolde, hvor koden netop skal starte den nye bold i den oprindelige bolds position, og med en ny retning.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  Ball(float x, float y, float xspeed, float yspeed) {&lt;br /&gt;
    this.x = x;&lt;br /&gt;
    this.y = y;&lt;br /&gt;
    this.xspeed = xspeed;&lt;br /&gt;
    this.yspeed = yspeed;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ud over disse standard ting til oprettelsen af objekter, så er der 3 metoder i klassen. Den første er en move() metode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  void move() {&lt;br /&gt;
    x = x + (xspeed * xdirection);&lt;br /&gt;
    y = y + (yspeed * ydirection);&lt;br /&gt;
&lt;br /&gt;
    if ((x + diameter/2 &amp;gt;= width) || (x - diameter/2 &amp;lt;= 0)) {&lt;br /&gt;
      xdirection *= -1;&lt;br /&gt;
    }&lt;br /&gt;
    if ((y + diameter/2 &amp;gt;= height) || (y - diameter/2 &amp;lt;= 0)) {&lt;br /&gt;
      ydirection *= -1;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Måden metoden virker på er at den lægger hastigheden til boldens position (både x og y), og hvis boldens position (både i x og y) er kommet uden for rammen, så ændres retningen for enten x eller y.&lt;br /&gt;
&lt;br /&gt;
For at kunne vise bolden er der en display() metode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  void display() {&lt;br /&gt;
    ellipse(x, y, diameter, diameter);&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Den sidste metode hedder contains(), og den tager en position som parameter til metoden. Der undersøges så om den position ligger inden for bolden ved at se om afstanden mellem boldens center og den testede position er mindre end den halve diameter. Hvis den er inden for bolden, så returneres true, ellers returneres false:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  boolean contains(float x, float y) {&lt;br /&gt;
    float d = dist(x, y, this.x, this.y);&lt;br /&gt;
    if (d &amp;lt; diameter/2) {&lt;br /&gt;
      return true;&lt;br /&gt;
    } else {&lt;br /&gt;
      return false;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Oprettelse af ny bold====&lt;br /&gt;
I den oprindelige kode undersøges om der er klikket på en bold, ved at alle bolde løbes igennem i mousePressed() funktionen, og med metoden contains undersøges om der er klikket på en bold. Denne måde at undersøge alle bolde på beholdes.&lt;br /&gt;
&lt;br /&gt;
Som omtalt er det ikke den smarteste måde til at dele bolden op i to, der anvendes. Som det ses i koden herunder, så appendes der to nye bolde på med den oprindelige bolds x- og y-position på samt tilfældige x- og y-hastigheder. Disse to bolde lægges i slutningen af arrayet. Derefter anvendes shorten&amp;lt;ref&amp;gt;[https://processing.org/reference/shorten_.html Processings shorten metode til arrays]&amp;lt;/ref&amp;gt; til at fjerne et element, men da det element der fjernes er det sidste element i arrayet, så fjernes der bare den sidst oprettede bold.&lt;br /&gt;
&lt;br /&gt;
Hvis man var tilfreds med den opførsel, så kunne man blot fjerne kodelinjen med den anden append og kodelinjen med shorten. Så ville man have samme funktion.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
    if (balls[i].contains(mouseX, mouseY)) {&lt;br /&gt;
      balls = (Ball[]) append(balls, new Ball(balls[i].x, balls[i].y, random(-5, 5), random(-5, 5)));&lt;br /&gt;
      balls = (Ball[]) append(balls, new Ball(balls[i].x, balls[i].y, random(-5, 5), random(-5, 5)));&lt;br /&gt;
      balls = (Ball[]) shorten(balls);&lt;br /&gt;
      break;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Den nye bold der oprettes får bare en tilfældig retning, og den oprindelige bold fortsætter bare i den retning den var på vej i. Det er ikke den opførsel der ønskes i spillet. Der ønskes i stedet at det ser ud som om bolden &amp;quot;splittes op&amp;quot; i 2 bolde, og den opførsel laves ved at lade den oprindelige bold ændre 30 grader til den ene side, og den nye bold får 30 grader til den anden side.&lt;br /&gt;
&lt;br /&gt;
For at gøre dette, så oprettes der en metode multiply() i klassen Ball. Denne metode returnerer en ny bold af typen Ball, så nu kan koden i museklikket skrives som følger:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
    if (balls[i].contains(mouseX, mouseY)) {&lt;br /&gt;
      balls = (Ball[]) append(balls, balls[i].multiply());&lt;br /&gt;
      break;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Som det kan ses, så appendes der en ny bold ind i balls-arrayet, ud fra metoden multiply().&lt;br /&gt;
&lt;br /&gt;
Metoden multiply() oprettes inde i klassen med følgende kode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  Ball multiply() {&lt;br /&gt;
    xspeed *= xdirection;&lt;br /&gt;
    yspeed *= ydirection;&lt;br /&gt;
    xdirection = 1;&lt;br /&gt;
    ydirection = 1;&lt;br /&gt;
    float speed = dist(0, 0, xspeed, yspeed);&lt;br /&gt;
    float angle = acos(xspeed / speed);&lt;br /&gt;
    if (yspeed &amp;lt; 0) angle = 0.0 - angle;&lt;br /&gt;
    speed *= 1.5;&lt;br /&gt;
    xspeed = speed * cos(angle + PI / 6);&lt;br /&gt;
    yspeed = speed * sin(angle + PI / 6);&lt;br /&gt;
    Ball b = new Ball(x, y, speed * cos(angle - PI / 6), speed * sin(angle - PI / 6));&lt;br /&gt;
    return b;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Først regnes retningen over i xspeed og yspeed, så de kan være både positive og negative. På den måde indeholder de to variabler retningen.&lt;br /&gt;
&lt;br /&gt;
Dernæst omregnes x- og y-hastigheden til en samlet hastighed speed og en vinkel angle, som kan være mellem +PI og -PI (+/- 180 grader).&lt;br /&gt;
&lt;br /&gt;
Begge bolde skal bevæge sig hurtigere efter de er delt, så spillet gradvist bliver sværere, derfor ganges hastigheden med 1,5.&lt;br /&gt;
&lt;br /&gt;
Den oprindelige bold får nu en ny retning, ved at udregne x- og y-hastigheden ud fra den nye hastighed og vinklen plus 30 grader.&lt;br /&gt;
&lt;br /&gt;
Til sidst oprettes en ny bold med samme position som den oprindelige og en x- og y-hastighed udregnet fra den oprindelige bolds hastighed og vinklen minus 30 grader. Denne bold returneres fra metoden.&lt;br /&gt;
&lt;br /&gt;
==Refleksioner over anvendelsen==&lt;br /&gt;
Der er selvfølgelig stadig lang vej til man har et færdigt spil, men ideen var også at tage fat i, hvordan man anvender ChatGPT på en ordentlig og redelig måde i et programmeringsprojekt. Dette kan selvfølgelig altid gradbøjes, men hvis man håndterer anvendelsen som vist i eksemplet, så vil man ikke gøre noget der kommer i nærheden af plagiat.&lt;br /&gt;
&lt;br /&gt;
==Referencer== &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt; &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Programmering}}&lt;br /&gt;
&lt;br /&gt;
[[Kategori:Programmering teknik]]&lt;/div&gt;</summary>
		<author><name>Bar</name></author>
	</entry>
	<entry>
		<id>https://www.htxarduino.dk/index.php?title=Programmering_med_ChatGPT&amp;diff=5411</id>
		<title>Programmering med ChatGPT</title>
		<link rel="alternate" type="text/html" href="https://www.htxarduino.dk/index.php?title=Programmering_med_ChatGPT&amp;diff=5411"/>
		<updated>2024-04-30T10:47:10Z</updated>

		<summary type="html">&lt;p&gt;Bar: /* Den meget nemmere metode */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Det er ikke så svært at få ChatGPT&amp;lt;ref&amp;gt;[https://chat.openai.com/auth/login ChatGPT Login] - Indgangen til ChatGPT&amp;lt;/ref&amp;gt; til at lave kode, der skal man blot beskrive hvad man gerne vil have programmet til at gøre, og så kopiere den kode, der kommer ud af det - det giver tit ret gode resultater.&lt;br /&gt;
&lt;br /&gt;
Problemet med at anvende ChatGPT i forbindelse med skoleprojekter er, at man skal have forståelsen med i det, og at man ikke kan blive anklaget for plagiat.&lt;br /&gt;
&lt;br /&gt;
==Hvad må man ikke i et skoleprojekt==&lt;br /&gt;
*Man må ikke kopiere kode, som man ikke selv har skrevet, til et programmeringsprodukt uden at man angiver en kilde. Det er uanset hvor koden stammer fra, også selvom man har brugt ChatGPT til at &amp;quot;udvikle&amp;quot; koden.&lt;br /&gt;
*Man må ikke aflevere et produkt hvor de primære dele af koden er kopieret, heller ikke selvom man kildehenviser.&lt;br /&gt;
*Man må ikke få ChatGPT til at dokumentere sin kode, ved at man kopierer ChatGPT&#039;s beskrivelse ind i sin dokumentation af koden.&lt;br /&gt;
&lt;br /&gt;
De beskrevne eksempler er at betragte som plagiat, og vil blive håndteret efter skolens ordensregler, hvilket i værste fald kan ende med at et fag annulleres eller man bliver bortvist fra uddannelsen.&lt;br /&gt;
&lt;br /&gt;
==Hvad er tilladt med ChatGPT==&lt;br /&gt;
På samme måde som man må anvende kilder fra internettet, så må man i programmerings-faget i gymnasiet anvende ChatGPT i udviklingen af kode til et programmeringsprodukt. Dette er blevet tilladt via en revidering af vejledningen til faget&amp;lt;ref&amp;gt;[https://www.uvm.dk/-/media/filer/uvm/udd/gym/pdf23/aug/vejledninger/valgfag/230807-programmering-c--valgfag.pdf Vejledning] til Valgfaget Programmering C&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
I vejledningen står der som følger:&lt;br /&gt;
&lt;br /&gt;
: &#039;&#039;&amp;quot;brug af internettet er tilladt som fagligt hjælpemiddel ved de mundtlige prøver, inkluderer de tilladte hjælpemidler anvendelsen af chatbots og lignende på en måde, som afspejler, hvordan man arbejder i den daglige undervisning. Dette kunne fx være brug af ChatGPT til at debugge kode.&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Det skal altså afspejle den normale brug, som man også har ved at bruge internettet. Som angivet under hvad man ikke må, så er den normale brug, at man anvender information til at lære at programmere, men at man ikke tager så meget af sit produkt fra nettet, så man ikke har en forståelse af hvordan produktet er sammensat.&lt;br /&gt;
&lt;br /&gt;
Videre i vejledningen står der:&lt;br /&gt;
&lt;br /&gt;
: &#039;&#039;&amp;quot;I forhold til denne type hjælpemidler er det vigtigt at være opmærksom på, at den tilladte anvendelse er betinget af, at hjælpemidlerne kun benyttes i et omfang, hvor prøvebesvarelsen er selvstændig og udelukkende elevens egen.&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Igen understreges at det der afleveres skal være elevens selvstændigt udviklede produkt og dokumentation, hvor man på normal vis anvender internettet som et værktøj til at bibringe forståelse.&lt;br /&gt;
&lt;br /&gt;
==Problemet med ChatGPT==&lt;br /&gt;
Ligesom man ikke kan kilde-henvise til &amp;quot;google&amp;quot;, for at angive at man har fundet informationer på nettet, så kan man heller ikke kildehenvise til ChatGPT direkte som en kilde.&lt;br /&gt;
&lt;br /&gt;
Når man finder informationer med google&#039;, så skal man angive hvor på nettet man har fundet dem med så præcis en kildehenvisning, at man kan se den information der er blevet anvendt.&lt;br /&gt;
&lt;br /&gt;
Denne type henvisning kan man ikke lave i forhold til ChatGPT, da sprogmodellen der ligger bag ChatGPT konstant udvikler sig, samt at de svar sprogmodellen giver har et randomiseret element indbygget, som er med til at give bedre svar&amp;lt;ref&amp;gt;[https://www.it-vest.dk/arrangementer/sig-webinar-14-marts-2024-kunstig-intelligens-og-chatgpt-hvordan-virker-det-og-skal-vi-bare-opgive-undervisning-og-eksamen Webinar om kunstig intelligens]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Her er man altså nødt til at tage andre metoder i brug, for at kunne dokumentere at man har udviklet sit produkt ordentligt og redeligt.&lt;br /&gt;
&lt;br /&gt;
==Kildehenvisninger i dokumentation==&lt;br /&gt;
Der kan være forskellige standarder for hvordan man kildehenviser i forskellige uddannelser, dette er skrevet med udgangspunkt i at man anvender Word bibliografi-værktøj og her vist med en Harvard-lignende standard&amp;lt;ref&amp;gt;[https://holstebro-htx.dk/index.php/Word_Kildeliste Kildelister] anvendt i Microsoft Word&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Normal Internet-kilde til kode===&lt;br /&gt;
I dette eksempel er der angivet hvordan man ville dokumentere at man har anvendt kode fra et bibliotek til noget hardware på en [[Arduino]]. I det tænkte eksempel er det en 4 kanals AD-konverter&amp;lt;ref&amp;gt;[https://arduinotech.dk/shop/ads1115-module-4-channel-16-bit-i2c-adc-with-pro-gain-amplifier 4 kanals AD-konverter] fra ArduinoTech&amp;lt;/ref&amp;gt;, der er købt som modul.&lt;br /&gt;
&lt;br /&gt;
For at kunne anvende modulet i koden skal der kommunikeres med modulet på en måde, som er angivet i beskrivelsen af modulet - det er dog ikke nødvendigt at sætte sig ind i den grundlæggende kommunikation, hvis man blot ønsker at få værdier ind i sin software. Som en dokumentation for hvordan man anvender biblioteket kan man skrive følgende:&lt;br /&gt;
&lt;br /&gt;
====Eksempel på dokumentation====&lt;br /&gt;
Til at hente værdierne fra den 4 kanals AD-konverter anvendes et bibliotek fundet på GitHub (Singh, 2018) som kan indlæse de analoge spændinger.&lt;br /&gt;
Til at sætte AD-konverteren rigtigt op, til at kunne læse 4 spændinger, så anvendes eksemplet ”ADS1115_SingleEnded.ino” og i setup skrives følgende kode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
    ads.getAddr_ADS1115(ADS1115_DEFAULT_ADDRESS);   // 0x48, 1001 000 (ADDR = GND)&lt;br /&gt;
    ads.setGain(GAIN_TWO);          // 2x gain   +/- 2.048V  1 bit = 0.0625mV (default)&lt;br /&gt;
    ads.setMode(MODE_CONTIN);       // Continuous conversion mode&lt;br /&gt;
    ads.setRate(RATE_128);          // 128SPS (default)&lt;br /&gt;
    ads.setOSMode(OSMODE_SINGLE);   // Set to start a single-conversion&lt;br /&gt;
    ads.begin();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
I [[loop()]] testes i første omgang, om det kan lade sig gøre at læse de 4 kanaler. Dette gøres ved at afvikle følgende testkode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
    address = ads.ads_i2cAddress;&lt;br /&gt;
    Wire.beginTransmission(address);&lt;br /&gt;
    error = Wire.endTransmission();&lt;br /&gt;
    if (error == 0)&lt;br /&gt;
    {&lt;br /&gt;
        int16_t adc0, adc1, adc2, adc3;&lt;br /&gt;
&lt;br /&gt;
        adc0 = ads.Measure_SingleEnded(0);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 1: &amp;quot;);&lt;br /&gt;
        Serial.println(adc0);&lt;br /&gt;
        adc1 = ads.Measure_SingleEnded(1);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 2: &amp;quot;);&lt;br /&gt;
        Serial.println(adc1);&lt;br /&gt;
        adc2 = ads.Measure_SingleEnded(2);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 3: &amp;quot;);&lt;br /&gt;
        Serial.println(adc2);&lt;br /&gt;
        adc3 = ads.Measure_SingleEnded(3);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 4: &amp;quot;);&lt;br /&gt;
        Serial.println(adc3);&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Denne test giver det ønskede resultat.&lt;br /&gt;
&lt;br /&gt;
Ud fra denne beskrivelse viser man, at man tager andres kode, og anvender ind i sit eget projekt, og man angiver præcist i sin beskrivelse hvad man har taget fra andres kode.&lt;br /&gt;
&lt;br /&gt;
I kildelisten vil kilden optræde på følgende måde:&lt;br /&gt;
&lt;br /&gt;
: Singh, Y., 2018. Arduino Library ADS1115 16 bit 4 channel ADC. [Online] &amp;lt;br /&amp;gt;&lt;br /&gt;
: Available at: https://github.com/ncdcommunity/Arduino_Library_ADS1115_16Bit_4Channel_ADC&amp;lt;br /&amp;gt;&lt;br /&gt;
: [Senest hentet eller vist den 15 marts 2024].&lt;br /&gt;
&lt;br /&gt;
===ChatGPT som kilde til kode===&lt;br /&gt;
Det følgende er skrevet med udgangspunkt i det der er beskrevet på viden.ai&amp;lt;ref&amp;gt;[https://viden.ai/korrekt-kildehenvisning-af-chatgpt/ Korrekt kildehenvisning af ChatGPT]&amp;lt;/ref&amp;gt;. hvor der angives hvordan man kildehenviser, men også lidt om hvordan man håndterer det i tekst - i korte træk, lav et metodeafsnit, beskriv hvad man gør og vær meget redelig, ved at man angiver hvad man har fået af ChatGPT ved at lægge det ved som et bilag.&lt;br /&gt;
&lt;br /&gt;
Hvis man forstår at prompte fornuftigt, så er ChatGPT faktisk ret god til at foreslå kode, der kan anvendes, men ligesom det er plagiat hvis man kopierer fra nettet, så er det plagiat, hvis man lader ChatGPT skrive store dele af ens program for sig.&lt;br /&gt;
&lt;br /&gt;
Som det er formuleret i vejledningen til både programmering C og B, så kan man anvende ChatGPT til hjælp i fejlfinding af kode. For at kunne kildehenvise korrekt til hjælp med fejlfinding, så skal man angive hvad man har promptet til ChatGPT og hvad den har svaret - det kan placeres i bilag.&lt;br /&gt;
&lt;br /&gt;
En anden ting, som også er OK at få hjælp med er, at komme i gang med programmet - det er denne problematik der her gives et eksempel på. I eksemplet beskrives hvad man skal skrive i sin dokumentation, når man har anvendt denne hjælp, og der er forslag til hvordan man kommer videre i projektet.&lt;br /&gt;
&lt;br /&gt;
Konkret er det starten på udviklingen af et lille spil med bolde i et vindue, udviklet i Processing, der tages udgangspunkt i.&lt;br /&gt;
&lt;br /&gt;
====Metodeafsnit med omtale af ChatGPT====&lt;br /&gt;
Når man anvender CharGPT, så skal man dokumentere hvordan man har gjort det, og hvilke overvejelser der ligger bag det. Det betegnes i rapportskrivning som et metodeafsnit. Det kunne i dette eksempel lyde:&lt;br /&gt;
&lt;br /&gt;
For at få en fornuftig start på programkoden er der brugt ChatGPT til at få rammerne på koden etableret, og til at få et system, så der kan optræde flere bolde i programvinduet. Det er ChatGPT 3.5 (OpenAI, 2023)&amp;lt;ref&amp;gt;[https://chat.openai.com/chat Indgangen til ChatGPT 3.5]&amp;lt;/ref&amp;gt; der er anvendt til denne hjælp. Til programstarten blev der promptet efter at få et programvindue på 800x600 hvor en bold bevæger sig rundt. Den foreslåede kode blev kopieret ind i processings IDE (Processing, 2024)&amp;lt;ref&amp;gt;[https://processing.org Hovedsiden for Processing]&amp;lt;/ref&amp;gt; og testet – den opførte sig som forventet.&lt;br /&gt;
&lt;br /&gt;
Derefter blev der promptet efter at få den bold der bevægede sig til at dele sig op i to, når man klikker på den med musen. Dette resulterede i en væsentligt anderledes kode, som igen blev kopieret ind i processing og testet, og igen med et acceptabelt resultat. Dialogen med ChatGPT (OpenAI, 2023) og herunder de to koder, kan ses i bilag 1.&lt;br /&gt;
&lt;br /&gt;
Herefter er resten af koden udviklet på traditionel vis, hvor første trin var at dokumentere princippet i den foreslåede kode, specielt den Ball klasse der blev introduceret for at kunne arbejde med flere bolde i vinduet.&lt;br /&gt;
&lt;br /&gt;
Det nævnte bilag 1 [[media:ChatGPT-dialog-1.pdf|kan ses i denne PDF]].&lt;br /&gt;
&lt;br /&gt;
Når man opretter kilden i Word, så er det lidt forskelligt hvilke felter der er synlige, alt efter hvilken standard man har aktiv - men ved Harvard-Anglia standarden kan indtastningerne se således ud:&lt;br /&gt;
&lt;br /&gt;
[[fil:citat-ChatGPT.png|Indtastningerne ved kildehenvisning til ChatGPT|600px]]&amp;lt;br /&amp;gt;&#039;&#039;Indtastningerne ved kildehenvisning til ChatGPT&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Mere om teknikken i at anvende kildelister kan ses på [https://holstebro-htx.dk/index.php/Word_Kildeliste Holstebro HTX Wiki - Kildelister].&lt;br /&gt;
&lt;br /&gt;
====Den meget nemmere metode====&lt;br /&gt;
Tingene udvikler sig hele tiden, og nu kan man faktisk få et link til den dialog man har haft med ChatGPT 3.5.&lt;br /&gt;
&lt;br /&gt;
Måden man gør det på er, at man klikker på en ikon i øverste højre side af websiden med den dialog man gerne vil linke til, som vist herunder, hvor man kommer i en dialog, så man kan kopiere linket.&amp;lt;br /&amp;gt;&lt;br /&gt;
[[img:link_til_chatGPT.png|Link ikon til dialog i chatGPT]]&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Link ikon til dialog i chatGPT&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Selve linket ser ud som følger: [https://chat.openai.com/share/90e9607f-bff9-40d1-a68c-9617051e9615].&lt;br /&gt;
&lt;br /&gt;
====Dokumentation af koden udviklet af ChatGPT====&lt;br /&gt;
Da der skulle kunne dannes nye bolde så oprettes der en klasse, som ChatGPT skriver det i dialogen i Bilag 1:&lt;br /&gt;
&lt;br /&gt;
: &#039;&#039;&amp;quot;Dette kodeeksempel opretter en klasse kaldet Ball, som repræsenterer boldobjekterne. Når musen klikkes, kontrolleres det, om musens position er inden for en bold. Hvis det er tilfældet, oprettes to nye boldobjekter, der bevæger sig i forskellige retninger, og den originale bold fjernes fra arrayet.&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Ved at teste koden kan man se at det ikke er det helt rigtige den formulerer - der oprettes godt nok to nye bold-objekter, men det er ikke den oprindelige bold der fjernes, det er den ene af de ny-oprettede bolde. Det kan ses ved at de to bolde kommer i samme position, og den ene fortsætter i samme retning (den oprindelige), mens den ny-oprettede går i en tilfældig retning. Dette rettes til senere i dokumentationen under &amp;quot;oprettelse af ny bold&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
For at have en god struktur i koden, så placeres klassen Ball i en fil for sig kaldet Ball. Denne fil starter med at definere koden som en klasse med linjen:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
class Ball {&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dernæst defineres klassens egenskaber, der er boldens position og hastighed samt en fast diameter. Ud over det er der en x- og y-retning defineret. Den anvendes til at sige om bolden bevæger sig i en positiv eller negativ retning, så de skifter mellem +1 og -1, når kanterne rammes.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  float x, y;&lt;br /&gt;
  float xspeed, yspeed;&lt;br /&gt;
  int diameter = 30;&lt;br /&gt;
  int xdirection = 1;&lt;br /&gt;
  int ydirection = 1;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der defineres to forskellige constructors til bolden. Den første anvendes til at danne den første bold med, hvor position og hastighed sættes tilfældigt.&lt;br /&gt;
&lt;br /&gt;
Her forudses et problem at der kan komme et randfænomen, hvis bolden dannes, så den ligger med noget uden for skærmen. Da det er tilfældigt; så er det sjældent problemet opstår. For at fremprovokere det oftere er det testet med en diameter på 200, hvor det kunne ses at bolden bliver &amp;quot;hængende&amp;quot; i kanten.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  Ball() {&lt;br /&gt;
    x = random(width);&lt;br /&gt;
    y = random(height);&lt;br /&gt;
    xspeed = random(0.5, 2);&lt;br /&gt;
    yspeed = random(0.5, 2);&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Dette rettes ved at omskrive den foreslåede constructor til følgende kode, hvor bolden placeres mindst en halv diameter fra kanten:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  Ball() {&lt;br /&gt;
    x = random(diameter / 2, width - diameter / 2);&lt;br /&gt;
    y = random(diameter / 2, height - diameter / 2);&lt;br /&gt;
    xspeed = random(0.5, 2);&lt;br /&gt;
    yspeed = random(0.5, 2);&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Den anden constructor tager fire parametre, der er positionen og hastigheden. Denne constructor anvendes, når der skal dannes nye bolde, hvor koden netop skal starte den nye bold i den oprindelige bolds position, og med en ny retning.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  Ball(float x, float y, float xspeed, float yspeed) {&lt;br /&gt;
    this.x = x;&lt;br /&gt;
    this.y = y;&lt;br /&gt;
    this.xspeed = xspeed;&lt;br /&gt;
    this.yspeed = yspeed;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ud over disse standard ting til oprettelsen af objekter, så er der 3 metoder i klassen. Den første er en move() metode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  void move() {&lt;br /&gt;
    x = x + (xspeed * xdirection);&lt;br /&gt;
    y = y + (yspeed * ydirection);&lt;br /&gt;
&lt;br /&gt;
    if ((x + diameter/2 &amp;gt;= width) || (x - diameter/2 &amp;lt;= 0)) {&lt;br /&gt;
      xdirection *= -1;&lt;br /&gt;
    }&lt;br /&gt;
    if ((y + diameter/2 &amp;gt;= height) || (y - diameter/2 &amp;lt;= 0)) {&lt;br /&gt;
      ydirection *= -1;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Måden metoden virker på er at den lægger hastigheden til boldens position (både x og y), og hvis boldens position (både i x og y) er kommet uden for rammen, så ændres retningen for enten x eller y.&lt;br /&gt;
&lt;br /&gt;
For at kunne vise bolden er der en display() metode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  void display() {&lt;br /&gt;
    ellipse(x, y, diameter, diameter);&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Den sidste metode hedder contains(), og den tager en position som parameter til metoden. Der undersøges så om den position ligger inden for bolden ved at se om afstanden mellem boldens center og den testede position er mindre end den halve diameter. Hvis den er inden for bolden, så returneres true, ellers returneres false:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  boolean contains(float x, float y) {&lt;br /&gt;
    float d = dist(x, y, this.x, this.y);&lt;br /&gt;
    if (d &amp;lt; diameter/2) {&lt;br /&gt;
      return true;&lt;br /&gt;
    } else {&lt;br /&gt;
      return false;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Oprettelse af ny bold====&lt;br /&gt;
I den oprindelige kode undersøges om der er klikket på en bold, ved at alle bolde løbes igennem i mousePressed() funktionen, og med metoden contains undersøges om der er klikket på en bold. Denne måde at undersøge alle bolde på beholdes.&lt;br /&gt;
&lt;br /&gt;
Som omtalt er det ikke den smarteste måde til at dele bolden op i to, der anvendes. Som det ses i koden herunder, så appendes der to nye bolde på med den oprindelige bolds x- og y-position på samt tilfældige x- og y-hastigheder. Disse to bolde lægges i slutningen af arrayet. Derefter anvendes shorten&amp;lt;ref&amp;gt;[https://processing.org/reference/shorten_.html Processings shorten metode til arrays]&amp;lt;/ref&amp;gt; til at fjerne et element, men da det element der fjernes er det sidste element i arrayet, så fjernes der bare den sidst oprettede bold.&lt;br /&gt;
&lt;br /&gt;
Hvis man var tilfreds med den opførsel, så kunne man blot fjerne kodelinjen med den anden append og kodelinjen med shorten. Så ville man have samme funktion.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
    if (balls[i].contains(mouseX, mouseY)) {&lt;br /&gt;
      balls = (Ball[]) append(balls, new Ball(balls[i].x, balls[i].y, random(-5, 5), random(-5, 5)));&lt;br /&gt;
      balls = (Ball[]) append(balls, new Ball(balls[i].x, balls[i].y, random(-5, 5), random(-5, 5)));&lt;br /&gt;
      balls = (Ball[]) shorten(balls);&lt;br /&gt;
      break;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Den nye bold der oprettes får bare en tilfældig retning, og den oprindelige bold fortsætter bare i den retning den var på vej i. Det er ikke den opførsel der ønskes i spillet. Der ønskes i stedet at det ser ud som om bolden &amp;quot;splittes op&amp;quot; i 2 bolde, og den opførsel laves ved at lade den oprindelige bold ændre 30 grader til den ene side, og den nye bold får 30 grader til den anden side.&lt;br /&gt;
&lt;br /&gt;
For at gøre dette, så oprettes der en metode multiply() i klassen Ball. Denne metode returnerer en ny bold af typen Ball, så nu kan koden i museklikket skrives som følger:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
    if (balls[i].contains(mouseX, mouseY)) {&lt;br /&gt;
      balls = (Ball[]) append(balls, balls[i].multiply());&lt;br /&gt;
      break;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Som det kan ses, så appendes der en ny bold ind i balls-arrayet, ud fra metoden multiply().&lt;br /&gt;
&lt;br /&gt;
Metoden multiply() oprettes inde i klassen med følgende kode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  Ball multiply() {&lt;br /&gt;
    xspeed *= xdirection;&lt;br /&gt;
    yspeed *= ydirection;&lt;br /&gt;
    xdirection = 1;&lt;br /&gt;
    ydirection = 1;&lt;br /&gt;
    float speed = dist(0, 0, xspeed, yspeed);&lt;br /&gt;
    float angle = acos(xspeed / speed);&lt;br /&gt;
    if (yspeed &amp;lt; 0) angle = 0.0 - angle;&lt;br /&gt;
    speed *= 1.5;&lt;br /&gt;
    xspeed = speed * cos(angle + PI / 6);&lt;br /&gt;
    yspeed = speed * sin(angle + PI / 6);&lt;br /&gt;
    Ball b = new Ball(x, y, speed * cos(angle - PI / 6), speed * sin(angle - PI / 6));&lt;br /&gt;
    return b;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Først regnes retningen over i xspeed og yspeed, så de kan være både positive og negative. På den måde indeholder de to variabler retningen.&lt;br /&gt;
&lt;br /&gt;
Dernæst omregnes x- og y-hastigheden til en samlet hastighed speed og en vinkel angle, som kan være mellem +PI og -PI (+/- 180 grader).&lt;br /&gt;
&lt;br /&gt;
Begge bolde skal bevæge sig hurtigere efter de er delt, så spillet gradvist bliver sværere, derfor ganges hastigheden med 1,5.&lt;br /&gt;
&lt;br /&gt;
Den oprindelige bold får nu en ny retning, ved at udregne x- og y-hastigheden ud fra den nye hastighed og vinklen plus 30 grader.&lt;br /&gt;
&lt;br /&gt;
Til sidst oprettes en ny bold med samme position som den oprindelige og en x- og y-hastighed udregnet fra den oprindelige bolds hastighed og vinklen minus 30 grader. Denne bold returneres fra metoden.&lt;br /&gt;
&lt;br /&gt;
==Refleksioner over anvendelsen==&lt;br /&gt;
Der er selvfølgelig stadig lang vej til man har et færdigt spil, men ideen var også at tage fat i, hvordan man anvender ChatGPT på en ordentlig og redelig måde i et programmeringsprojekt. Dette kan selvfølgelig altid gradbøjes, men hvis man håndterer anvendelsen som vist i eksemplet, så vil man ikke gøre noget der kommer i nærheden af plagiat.&lt;br /&gt;
&lt;br /&gt;
==Referencer== &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt; &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Programmering}}&lt;br /&gt;
&lt;br /&gt;
[[Kategori:Programmering teknik]]&lt;/div&gt;</summary>
		<author><name>Bar</name></author>
	</entry>
	<entry>
		<id>https://www.htxarduino.dk/index.php?title=Programmering_med_ChatGPT&amp;diff=5410</id>
		<title>Programmering med ChatGPT</title>
		<link rel="alternate" type="text/html" href="https://www.htxarduino.dk/index.php?title=Programmering_med_ChatGPT&amp;diff=5410"/>
		<updated>2024-04-30T10:43:15Z</updated>

		<summary type="html">&lt;p&gt;Bar: /* Metodeafsnit med omtale af ChatGPT */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Det er ikke så svært at få ChatGPT&amp;lt;ref&amp;gt;[https://chat.openai.com/auth/login ChatGPT Login] - Indgangen til ChatGPT&amp;lt;/ref&amp;gt; til at lave kode, der skal man blot beskrive hvad man gerne vil have programmet til at gøre, og så kopiere den kode, der kommer ud af det - det giver tit ret gode resultater.&lt;br /&gt;
&lt;br /&gt;
Problemet med at anvende ChatGPT i forbindelse med skoleprojekter er, at man skal have forståelsen med i det, og at man ikke kan blive anklaget for plagiat.&lt;br /&gt;
&lt;br /&gt;
==Hvad må man ikke i et skoleprojekt==&lt;br /&gt;
*Man må ikke kopiere kode, som man ikke selv har skrevet, til et programmeringsprodukt uden at man angiver en kilde. Det er uanset hvor koden stammer fra, også selvom man har brugt ChatGPT til at &amp;quot;udvikle&amp;quot; koden.&lt;br /&gt;
*Man må ikke aflevere et produkt hvor de primære dele af koden er kopieret, heller ikke selvom man kildehenviser.&lt;br /&gt;
*Man må ikke få ChatGPT til at dokumentere sin kode, ved at man kopierer ChatGPT&#039;s beskrivelse ind i sin dokumentation af koden.&lt;br /&gt;
&lt;br /&gt;
De beskrevne eksempler er at betragte som plagiat, og vil blive håndteret efter skolens ordensregler, hvilket i værste fald kan ende med at et fag annulleres eller man bliver bortvist fra uddannelsen.&lt;br /&gt;
&lt;br /&gt;
==Hvad er tilladt med ChatGPT==&lt;br /&gt;
På samme måde som man må anvende kilder fra internettet, så må man i programmerings-faget i gymnasiet anvende ChatGPT i udviklingen af kode til et programmeringsprodukt. Dette er blevet tilladt via en revidering af vejledningen til faget&amp;lt;ref&amp;gt;[https://www.uvm.dk/-/media/filer/uvm/udd/gym/pdf23/aug/vejledninger/valgfag/230807-programmering-c--valgfag.pdf Vejledning] til Valgfaget Programmering C&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
I vejledningen står der som følger:&lt;br /&gt;
&lt;br /&gt;
: &#039;&#039;&amp;quot;brug af internettet er tilladt som fagligt hjælpemiddel ved de mundtlige prøver, inkluderer de tilladte hjælpemidler anvendelsen af chatbots og lignende på en måde, som afspejler, hvordan man arbejder i den daglige undervisning. Dette kunne fx være brug af ChatGPT til at debugge kode.&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Det skal altså afspejle den normale brug, som man også har ved at bruge internettet. Som angivet under hvad man ikke må, så er den normale brug, at man anvender information til at lære at programmere, men at man ikke tager så meget af sit produkt fra nettet, så man ikke har en forståelse af hvordan produktet er sammensat.&lt;br /&gt;
&lt;br /&gt;
Videre i vejledningen står der:&lt;br /&gt;
&lt;br /&gt;
: &#039;&#039;&amp;quot;I forhold til denne type hjælpemidler er det vigtigt at være opmærksom på, at den tilladte anvendelse er betinget af, at hjælpemidlerne kun benyttes i et omfang, hvor prøvebesvarelsen er selvstændig og udelukkende elevens egen.&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Igen understreges at det der afleveres skal være elevens selvstændigt udviklede produkt og dokumentation, hvor man på normal vis anvender internettet som et værktøj til at bibringe forståelse.&lt;br /&gt;
&lt;br /&gt;
==Problemet med ChatGPT==&lt;br /&gt;
Ligesom man ikke kan kilde-henvise til &amp;quot;google&amp;quot;, for at angive at man har fundet informationer på nettet, så kan man heller ikke kildehenvise til ChatGPT direkte som en kilde.&lt;br /&gt;
&lt;br /&gt;
Når man finder informationer med google&#039;, så skal man angive hvor på nettet man har fundet dem med så præcis en kildehenvisning, at man kan se den information der er blevet anvendt.&lt;br /&gt;
&lt;br /&gt;
Denne type henvisning kan man ikke lave i forhold til ChatGPT, da sprogmodellen der ligger bag ChatGPT konstant udvikler sig, samt at de svar sprogmodellen giver har et randomiseret element indbygget, som er med til at give bedre svar&amp;lt;ref&amp;gt;[https://www.it-vest.dk/arrangementer/sig-webinar-14-marts-2024-kunstig-intelligens-og-chatgpt-hvordan-virker-det-og-skal-vi-bare-opgive-undervisning-og-eksamen Webinar om kunstig intelligens]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Her er man altså nødt til at tage andre metoder i brug, for at kunne dokumentere at man har udviklet sit produkt ordentligt og redeligt.&lt;br /&gt;
&lt;br /&gt;
==Kildehenvisninger i dokumentation==&lt;br /&gt;
Der kan være forskellige standarder for hvordan man kildehenviser i forskellige uddannelser, dette er skrevet med udgangspunkt i at man anvender Word bibliografi-værktøj og her vist med en Harvard-lignende standard&amp;lt;ref&amp;gt;[https://holstebro-htx.dk/index.php/Word_Kildeliste Kildelister] anvendt i Microsoft Word&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Normal Internet-kilde til kode===&lt;br /&gt;
I dette eksempel er der angivet hvordan man ville dokumentere at man har anvendt kode fra et bibliotek til noget hardware på en [[Arduino]]. I det tænkte eksempel er det en 4 kanals AD-konverter&amp;lt;ref&amp;gt;[https://arduinotech.dk/shop/ads1115-module-4-channel-16-bit-i2c-adc-with-pro-gain-amplifier 4 kanals AD-konverter] fra ArduinoTech&amp;lt;/ref&amp;gt;, der er købt som modul.&lt;br /&gt;
&lt;br /&gt;
For at kunne anvende modulet i koden skal der kommunikeres med modulet på en måde, som er angivet i beskrivelsen af modulet - det er dog ikke nødvendigt at sætte sig ind i den grundlæggende kommunikation, hvis man blot ønsker at få værdier ind i sin software. Som en dokumentation for hvordan man anvender biblioteket kan man skrive følgende:&lt;br /&gt;
&lt;br /&gt;
====Eksempel på dokumentation====&lt;br /&gt;
Til at hente værdierne fra den 4 kanals AD-konverter anvendes et bibliotek fundet på GitHub (Singh, 2018) som kan indlæse de analoge spændinger.&lt;br /&gt;
Til at sætte AD-konverteren rigtigt op, til at kunne læse 4 spændinger, så anvendes eksemplet ”ADS1115_SingleEnded.ino” og i setup skrives følgende kode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
    ads.getAddr_ADS1115(ADS1115_DEFAULT_ADDRESS);   // 0x48, 1001 000 (ADDR = GND)&lt;br /&gt;
    ads.setGain(GAIN_TWO);          // 2x gain   +/- 2.048V  1 bit = 0.0625mV (default)&lt;br /&gt;
    ads.setMode(MODE_CONTIN);       // Continuous conversion mode&lt;br /&gt;
    ads.setRate(RATE_128);          // 128SPS (default)&lt;br /&gt;
    ads.setOSMode(OSMODE_SINGLE);   // Set to start a single-conversion&lt;br /&gt;
    ads.begin();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
I [[loop()]] testes i første omgang, om det kan lade sig gøre at læse de 4 kanaler. Dette gøres ved at afvikle følgende testkode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
    address = ads.ads_i2cAddress;&lt;br /&gt;
    Wire.beginTransmission(address);&lt;br /&gt;
    error = Wire.endTransmission();&lt;br /&gt;
    if (error == 0)&lt;br /&gt;
    {&lt;br /&gt;
        int16_t adc0, adc1, adc2, adc3;&lt;br /&gt;
&lt;br /&gt;
        adc0 = ads.Measure_SingleEnded(0);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 1: &amp;quot;);&lt;br /&gt;
        Serial.println(adc0);&lt;br /&gt;
        adc1 = ads.Measure_SingleEnded(1);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 2: &amp;quot;);&lt;br /&gt;
        Serial.println(adc1);&lt;br /&gt;
        adc2 = ads.Measure_SingleEnded(2);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 3: &amp;quot;);&lt;br /&gt;
        Serial.println(adc2);&lt;br /&gt;
        adc3 = ads.Measure_SingleEnded(3);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 4: &amp;quot;);&lt;br /&gt;
        Serial.println(adc3);&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Denne test giver det ønskede resultat.&lt;br /&gt;
&lt;br /&gt;
Ud fra denne beskrivelse viser man, at man tager andres kode, og anvender ind i sit eget projekt, og man angiver præcist i sin beskrivelse hvad man har taget fra andres kode.&lt;br /&gt;
&lt;br /&gt;
I kildelisten vil kilden optræde på følgende måde:&lt;br /&gt;
&lt;br /&gt;
: Singh, Y., 2018. Arduino Library ADS1115 16 bit 4 channel ADC. [Online] &amp;lt;br /&amp;gt;&lt;br /&gt;
: Available at: https://github.com/ncdcommunity/Arduino_Library_ADS1115_16Bit_4Channel_ADC&amp;lt;br /&amp;gt;&lt;br /&gt;
: [Senest hentet eller vist den 15 marts 2024].&lt;br /&gt;
&lt;br /&gt;
===ChatGPT som kilde til kode===&lt;br /&gt;
Det følgende er skrevet med udgangspunkt i det der er beskrevet på viden.ai&amp;lt;ref&amp;gt;[https://viden.ai/korrekt-kildehenvisning-af-chatgpt/ Korrekt kildehenvisning af ChatGPT]&amp;lt;/ref&amp;gt;. hvor der angives hvordan man kildehenviser, men også lidt om hvordan man håndterer det i tekst - i korte træk, lav et metodeafsnit, beskriv hvad man gør og vær meget redelig, ved at man angiver hvad man har fået af ChatGPT ved at lægge det ved som et bilag.&lt;br /&gt;
&lt;br /&gt;
Hvis man forstår at prompte fornuftigt, så er ChatGPT faktisk ret god til at foreslå kode, der kan anvendes, men ligesom det er plagiat hvis man kopierer fra nettet, så er det plagiat, hvis man lader ChatGPT skrive store dele af ens program for sig.&lt;br /&gt;
&lt;br /&gt;
Som det er formuleret i vejledningen til både programmering C og B, så kan man anvende ChatGPT til hjælp i fejlfinding af kode. For at kunne kildehenvise korrekt til hjælp med fejlfinding, så skal man angive hvad man har promptet til ChatGPT og hvad den har svaret - det kan placeres i bilag.&lt;br /&gt;
&lt;br /&gt;
En anden ting, som også er OK at få hjælp med er, at komme i gang med programmet - det er denne problematik der her gives et eksempel på. I eksemplet beskrives hvad man skal skrive i sin dokumentation, når man har anvendt denne hjælp, og der er forslag til hvordan man kommer videre i projektet.&lt;br /&gt;
&lt;br /&gt;
Konkret er det starten på udviklingen af et lille spil med bolde i et vindue, udviklet i Processing, der tages udgangspunkt i.&lt;br /&gt;
&lt;br /&gt;
====Metodeafsnit med omtale af ChatGPT====&lt;br /&gt;
Når man anvender CharGPT, så skal man dokumentere hvordan man har gjort det, og hvilke overvejelser der ligger bag det. Det betegnes i rapportskrivning som et metodeafsnit. Det kunne i dette eksempel lyde:&lt;br /&gt;
&lt;br /&gt;
For at få en fornuftig start på programkoden er der brugt ChatGPT til at få rammerne på koden etableret, og til at få et system, så der kan optræde flere bolde i programvinduet. Det er ChatGPT 3.5 (OpenAI, 2023)&amp;lt;ref&amp;gt;[https://chat.openai.com/chat Indgangen til ChatGPT 3.5]&amp;lt;/ref&amp;gt; der er anvendt til denne hjælp. Til programstarten blev der promptet efter at få et programvindue på 800x600 hvor en bold bevæger sig rundt. Den foreslåede kode blev kopieret ind i processings IDE (Processing, 2024)&amp;lt;ref&amp;gt;[https://processing.org Hovedsiden for Processing]&amp;lt;/ref&amp;gt; og testet – den opførte sig som forventet.&lt;br /&gt;
&lt;br /&gt;
Derefter blev der promptet efter at få den bold der bevægede sig til at dele sig op i to, når man klikker på den med musen. Dette resulterede i en væsentligt anderledes kode, som igen blev kopieret ind i processing og testet, og igen med et acceptabelt resultat. Dialogen med ChatGPT (OpenAI, 2023) og herunder de to koder, kan ses i bilag 1.&lt;br /&gt;
&lt;br /&gt;
Herefter er resten af koden udviklet på traditionel vis, hvor første trin var at dokumentere princippet i den foreslåede kode, specielt den Ball klasse der blev introduceret for at kunne arbejde med flere bolde i vinduet.&lt;br /&gt;
&lt;br /&gt;
Det nævnte bilag 1 [[media:ChatGPT-dialog-1.pdf|kan ses i denne PDF]].&lt;br /&gt;
&lt;br /&gt;
Når man opretter kilden i Word, så er det lidt forskelligt hvilke felter der er synlige, alt efter hvilken standard man har aktiv - men ved Harvard-Anglia standarden kan indtastningerne se således ud:&lt;br /&gt;
&lt;br /&gt;
[[fil:citat-ChatGPT.png|Indtastningerne ved kildehenvisning til ChatGPT|600px]]&amp;lt;br /&amp;gt;&#039;&#039;Indtastningerne ved kildehenvisning til ChatGPT&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Mere om teknikken i at anvende kildelister kan ses på [https://holstebro-htx.dk/index.php/Word_Kildeliste Holstebro HTX Wiki - Kildelister].&lt;br /&gt;
&lt;br /&gt;
====Den meget nemmere metode====&lt;br /&gt;
Tingene udvikler sig hele tiden, og nu kan man faktisk få et link til den dialog man har haft med ChatGPT 3.5.&lt;br /&gt;
&lt;br /&gt;
Måden man gør det på er, at man klikker på en ikon i øverste højre side af websiden med den dialog man gerne vil linke til, som vist herunder, hvor man kommer i en dialog, så man kan kopiere linket.&amp;lt;br /&amp;gt;&lt;br /&gt;
[img:link_til_chatGPT.png|Link ikon til dialog i chatGPT]&amp;lt;br /&amp;gt;&lt;br /&gt;
&#039;&#039;&#039;Link ikon til dialog i chatGPT&#039;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Selve linket ser ud som følger: [https://chat.openai.com/share/90e9607f-bff9-40d1-a68c-9617051e9615].&lt;br /&gt;
&lt;br /&gt;
====Dokumentation af koden udviklet af ChatGPT====&lt;br /&gt;
Da der skulle kunne dannes nye bolde så oprettes der en klasse, som ChatGPT skriver det i dialogen i Bilag 1:&lt;br /&gt;
&lt;br /&gt;
: &#039;&#039;&amp;quot;Dette kodeeksempel opretter en klasse kaldet Ball, som repræsenterer boldobjekterne. Når musen klikkes, kontrolleres det, om musens position er inden for en bold. Hvis det er tilfældet, oprettes to nye boldobjekter, der bevæger sig i forskellige retninger, og den originale bold fjernes fra arrayet.&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Ved at teste koden kan man se at det ikke er det helt rigtige den formulerer - der oprettes godt nok to nye bold-objekter, men det er ikke den oprindelige bold der fjernes, det er den ene af de ny-oprettede bolde. Det kan ses ved at de to bolde kommer i samme position, og den ene fortsætter i samme retning (den oprindelige), mens den ny-oprettede går i en tilfældig retning. Dette rettes til senere i dokumentationen under &amp;quot;oprettelse af ny bold&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
For at have en god struktur i koden, så placeres klassen Ball i en fil for sig kaldet Ball. Denne fil starter med at definere koden som en klasse med linjen:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
class Ball {&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dernæst defineres klassens egenskaber, der er boldens position og hastighed samt en fast diameter. Ud over det er der en x- og y-retning defineret. Den anvendes til at sige om bolden bevæger sig i en positiv eller negativ retning, så de skifter mellem +1 og -1, når kanterne rammes.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  float x, y;&lt;br /&gt;
  float xspeed, yspeed;&lt;br /&gt;
  int diameter = 30;&lt;br /&gt;
  int xdirection = 1;&lt;br /&gt;
  int ydirection = 1;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der defineres to forskellige constructors til bolden. Den første anvendes til at danne den første bold med, hvor position og hastighed sættes tilfældigt.&lt;br /&gt;
&lt;br /&gt;
Her forudses et problem at der kan komme et randfænomen, hvis bolden dannes, så den ligger med noget uden for skærmen. Da det er tilfældigt; så er det sjældent problemet opstår. For at fremprovokere det oftere er det testet med en diameter på 200, hvor det kunne ses at bolden bliver &amp;quot;hængende&amp;quot; i kanten.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  Ball() {&lt;br /&gt;
    x = random(width);&lt;br /&gt;
    y = random(height);&lt;br /&gt;
    xspeed = random(0.5, 2);&lt;br /&gt;
    yspeed = random(0.5, 2);&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Dette rettes ved at omskrive den foreslåede constructor til følgende kode, hvor bolden placeres mindst en halv diameter fra kanten:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  Ball() {&lt;br /&gt;
    x = random(diameter / 2, width - diameter / 2);&lt;br /&gt;
    y = random(diameter / 2, height - diameter / 2);&lt;br /&gt;
    xspeed = random(0.5, 2);&lt;br /&gt;
    yspeed = random(0.5, 2);&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Den anden constructor tager fire parametre, der er positionen og hastigheden. Denne constructor anvendes, når der skal dannes nye bolde, hvor koden netop skal starte den nye bold i den oprindelige bolds position, og med en ny retning.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  Ball(float x, float y, float xspeed, float yspeed) {&lt;br /&gt;
    this.x = x;&lt;br /&gt;
    this.y = y;&lt;br /&gt;
    this.xspeed = xspeed;&lt;br /&gt;
    this.yspeed = yspeed;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ud over disse standard ting til oprettelsen af objekter, så er der 3 metoder i klassen. Den første er en move() metode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  void move() {&lt;br /&gt;
    x = x + (xspeed * xdirection);&lt;br /&gt;
    y = y + (yspeed * ydirection);&lt;br /&gt;
&lt;br /&gt;
    if ((x + diameter/2 &amp;gt;= width) || (x - diameter/2 &amp;lt;= 0)) {&lt;br /&gt;
      xdirection *= -1;&lt;br /&gt;
    }&lt;br /&gt;
    if ((y + diameter/2 &amp;gt;= height) || (y - diameter/2 &amp;lt;= 0)) {&lt;br /&gt;
      ydirection *= -1;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Måden metoden virker på er at den lægger hastigheden til boldens position (både x og y), og hvis boldens position (både i x og y) er kommet uden for rammen, så ændres retningen for enten x eller y.&lt;br /&gt;
&lt;br /&gt;
For at kunne vise bolden er der en display() metode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  void display() {&lt;br /&gt;
    ellipse(x, y, diameter, diameter);&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Den sidste metode hedder contains(), og den tager en position som parameter til metoden. Der undersøges så om den position ligger inden for bolden ved at se om afstanden mellem boldens center og den testede position er mindre end den halve diameter. Hvis den er inden for bolden, så returneres true, ellers returneres false:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  boolean contains(float x, float y) {&lt;br /&gt;
    float d = dist(x, y, this.x, this.y);&lt;br /&gt;
    if (d &amp;lt; diameter/2) {&lt;br /&gt;
      return true;&lt;br /&gt;
    } else {&lt;br /&gt;
      return false;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Oprettelse af ny bold====&lt;br /&gt;
I den oprindelige kode undersøges om der er klikket på en bold, ved at alle bolde løbes igennem i mousePressed() funktionen, og med metoden contains undersøges om der er klikket på en bold. Denne måde at undersøge alle bolde på beholdes.&lt;br /&gt;
&lt;br /&gt;
Som omtalt er det ikke den smarteste måde til at dele bolden op i to, der anvendes. Som det ses i koden herunder, så appendes der to nye bolde på med den oprindelige bolds x- og y-position på samt tilfældige x- og y-hastigheder. Disse to bolde lægges i slutningen af arrayet. Derefter anvendes shorten&amp;lt;ref&amp;gt;[https://processing.org/reference/shorten_.html Processings shorten metode til arrays]&amp;lt;/ref&amp;gt; til at fjerne et element, men da det element der fjernes er det sidste element i arrayet, så fjernes der bare den sidst oprettede bold.&lt;br /&gt;
&lt;br /&gt;
Hvis man var tilfreds med den opførsel, så kunne man blot fjerne kodelinjen med den anden append og kodelinjen med shorten. Så ville man have samme funktion.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
    if (balls[i].contains(mouseX, mouseY)) {&lt;br /&gt;
      balls = (Ball[]) append(balls, new Ball(balls[i].x, balls[i].y, random(-5, 5), random(-5, 5)));&lt;br /&gt;
      balls = (Ball[]) append(balls, new Ball(balls[i].x, balls[i].y, random(-5, 5), random(-5, 5)));&lt;br /&gt;
      balls = (Ball[]) shorten(balls);&lt;br /&gt;
      break;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Den nye bold der oprettes får bare en tilfældig retning, og den oprindelige bold fortsætter bare i den retning den var på vej i. Det er ikke den opførsel der ønskes i spillet. Der ønskes i stedet at det ser ud som om bolden &amp;quot;splittes op&amp;quot; i 2 bolde, og den opførsel laves ved at lade den oprindelige bold ændre 30 grader til den ene side, og den nye bold får 30 grader til den anden side.&lt;br /&gt;
&lt;br /&gt;
For at gøre dette, så oprettes der en metode multiply() i klassen Ball. Denne metode returnerer en ny bold af typen Ball, så nu kan koden i museklikket skrives som følger:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
    if (balls[i].contains(mouseX, mouseY)) {&lt;br /&gt;
      balls = (Ball[]) append(balls, balls[i].multiply());&lt;br /&gt;
      break;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Som det kan ses, så appendes der en ny bold ind i balls-arrayet, ud fra metoden multiply().&lt;br /&gt;
&lt;br /&gt;
Metoden multiply() oprettes inde i klassen med følgende kode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  Ball multiply() {&lt;br /&gt;
    xspeed *= xdirection;&lt;br /&gt;
    yspeed *= ydirection;&lt;br /&gt;
    xdirection = 1;&lt;br /&gt;
    ydirection = 1;&lt;br /&gt;
    float speed = dist(0, 0, xspeed, yspeed);&lt;br /&gt;
    float angle = acos(xspeed / speed);&lt;br /&gt;
    if (yspeed &amp;lt; 0) angle = 0.0 - angle;&lt;br /&gt;
    speed *= 1.5;&lt;br /&gt;
    xspeed = speed * cos(angle + PI / 6);&lt;br /&gt;
    yspeed = speed * sin(angle + PI / 6);&lt;br /&gt;
    Ball b = new Ball(x, y, speed * cos(angle - PI / 6), speed * sin(angle - PI / 6));&lt;br /&gt;
    return b;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Først regnes retningen over i xspeed og yspeed, så de kan være både positive og negative. På den måde indeholder de to variabler retningen.&lt;br /&gt;
&lt;br /&gt;
Dernæst omregnes x- og y-hastigheden til en samlet hastighed speed og en vinkel angle, som kan være mellem +PI og -PI (+/- 180 grader).&lt;br /&gt;
&lt;br /&gt;
Begge bolde skal bevæge sig hurtigere efter de er delt, så spillet gradvist bliver sværere, derfor ganges hastigheden med 1,5.&lt;br /&gt;
&lt;br /&gt;
Den oprindelige bold får nu en ny retning, ved at udregne x- og y-hastigheden ud fra den nye hastighed og vinklen plus 30 grader.&lt;br /&gt;
&lt;br /&gt;
Til sidst oprettes en ny bold med samme position som den oprindelige og en x- og y-hastighed udregnet fra den oprindelige bolds hastighed og vinklen minus 30 grader. Denne bold returneres fra metoden.&lt;br /&gt;
&lt;br /&gt;
==Refleksioner over anvendelsen==&lt;br /&gt;
Der er selvfølgelig stadig lang vej til man har et færdigt spil, men ideen var også at tage fat i, hvordan man anvender ChatGPT på en ordentlig og redelig måde i et programmeringsprojekt. Dette kan selvfølgelig altid gradbøjes, men hvis man håndterer anvendelsen som vist i eksemplet, så vil man ikke gøre noget der kommer i nærheden af plagiat.&lt;br /&gt;
&lt;br /&gt;
==Referencer== &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt; &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Programmering}}&lt;br /&gt;
&lt;br /&gt;
[[Kategori:Programmering teknik]]&lt;/div&gt;</summary>
		<author><name>Bar</name></author>
	</entry>
	<entry>
		<id>https://www.htxarduino.dk/index.php?title=Komponent&amp;diff=5409</id>
		<title>Komponent</title>
		<link rel="alternate" type="text/html" href="https://www.htxarduino.dk/index.php?title=Komponent&amp;diff=5409"/>
		<updated>2024-04-09T18:07:34Z</updated>

		<summary type="html">&lt;p&gt;Bar: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Komponentliste https://www.holstebro-htx.dk/el/komp.php&lt;br /&gt;
==Byggestenene==&lt;br /&gt;
Elektronik er opbygget af forskellige komponenter, hvor man typisk skelner mellem [[analog]]e og [[digital]]e komponenter.&lt;br /&gt;
&lt;br /&gt;
Mange komponenter kan anvendes både i analoge og digitale opstillinger, men de har lidt forskellig funktion, alt efter hvordan de anvendes. En [[transistor]] kan anvendes som en kontakt, altså en digital komponent, og den kan anvendes som analog forstærker. I begge tilfælde skal der også modstande med i kredsløbet, altså igen kan modstanden indgå i begge typer kredsløb.&lt;br /&gt;
&lt;br /&gt;
==Lager==&lt;br /&gt;
På Holstebro HTX forsøger vi at have et fornuftigt lager af de gængse komponenter der anvendes i undervisningen. En del af disse komponenter er registreret i vores lagersystem&amp;lt;ref&amp;gt;https://www.holstebro-htx.dk/el/komp.php vores lagersystem på Holstebro HTX&amp;lt;/ref&amp;gt;, hvor man kan finde datablad for komponenten, i nogle tilfælde prisen (eller en standard pris på 3,00), og hvor man kan finde komponenten i lokalet.&lt;br /&gt;
&lt;br /&gt;
==Moduler==&lt;br /&gt;
Ud over komponenter har vi også en del små moduler, specielt til [[Arduino]] på lager - de ligger i en separat liste under Moduler på https://www.holstebro-htx.dk/el/modul.php&lt;br /&gt;
&lt;br /&gt;
==Referencer==&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{analog}}&lt;br /&gt;
&lt;br /&gt;
[[Kategori:Værkstedet]]&lt;/div&gt;</summary>
		<author><name>Bar</name></author>
	</entry>
	<entry>
		<id>https://www.htxarduino.dk/index.php?title=Programmering_med_ChatGPT&amp;diff=5408</id>
		<title>Programmering med ChatGPT</title>
		<link rel="alternate" type="text/html" href="https://www.htxarduino.dk/index.php?title=Programmering_med_ChatGPT&amp;diff=5408"/>
		<updated>2024-03-20T10:12:38Z</updated>

		<summary type="html">&lt;p&gt;Bar: /* Metodeafsnit med omtale af ChatGPT */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Det er ikke så svært at få ChatGPT&amp;lt;ref&amp;gt;[https://chat.openai.com/auth/login ChatGPT Login] - Indgangen til ChatGPT&amp;lt;/ref&amp;gt; til at lave kode, der skal man blot beskrive hvad man gerne vil have programmet til at gøre, og så kopiere den kode, der kommer ud af det - det giver tit ret gode resultater.&lt;br /&gt;
&lt;br /&gt;
Problemet med at anvende ChatGPT i forbindelse med skoleprojekter er, at man skal have forståelsen med i det, og at man ikke kan blive anklaget for plagiat.&lt;br /&gt;
&lt;br /&gt;
==Hvad må man ikke i et skoleprojekt==&lt;br /&gt;
*Man må ikke kopiere kode, som man ikke selv har skrevet, til et programmeringsprodukt uden at man angiver en kilde. Det er uanset hvor koden stammer fra, også selvom man har brugt ChatGPT til at &amp;quot;udvikle&amp;quot; koden.&lt;br /&gt;
*Man må ikke aflevere et produkt hvor de primære dele af koden er kopieret, heller ikke selvom man kildehenviser.&lt;br /&gt;
*Man må ikke få ChatGPT til at dokumentere sin kode, ved at man kopierer ChatGPT&#039;s beskrivelse ind i sin dokumentation af koden.&lt;br /&gt;
&lt;br /&gt;
De beskrevne eksempler er at betragte som plagiat, og vil blive håndteret efter skolens ordensregler, hvilket i værste fald kan ende med at et fag annulleres eller man bliver bortvist fra uddannelsen.&lt;br /&gt;
&lt;br /&gt;
==Hvad er tilladt med ChatGPT==&lt;br /&gt;
På samme måde som man må anvende kilder fra internettet, så må man i programmerings-faget i gymnasiet anvende ChatGPT i udviklingen af kode til et programmeringsprodukt. Dette er blevet tilladt via en revidering af vejledningen til faget&amp;lt;ref&amp;gt;[https://www.uvm.dk/-/media/filer/uvm/udd/gym/pdf23/aug/vejledninger/valgfag/230807-programmering-c--valgfag.pdf Vejledning] til Valgfaget Programmering C&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
I vejledningen står der som følger:&lt;br /&gt;
&lt;br /&gt;
: &#039;&#039;&amp;quot;brug af internettet er tilladt som fagligt hjælpemiddel ved de mundtlige prøver, inkluderer de tilladte hjælpemidler anvendelsen af chatbots og lignende på en måde, som afspejler, hvordan man arbejder i den daglige undervisning. Dette kunne fx være brug af ChatGPT til at debugge kode.&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Det skal altså afspejle den normale brug, som man også har ved at bruge internettet. Som angivet under hvad man ikke må, så er den normale brug, at man anvender information til at lære at programmere, men at man ikke tager så meget af sit produkt fra nettet, så man ikke har en forståelse af hvordan produktet er sammensat.&lt;br /&gt;
&lt;br /&gt;
Videre i vejledningen står der:&lt;br /&gt;
&lt;br /&gt;
: &#039;&#039;&amp;quot;I forhold til denne type hjælpemidler er det vigtigt at være opmærksom på, at den tilladte anvendelse er betinget af, at hjælpemidlerne kun benyttes i et omfang, hvor prøvebesvarelsen er selvstændig og udelukkende elevens egen.&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Igen understreges at det der afleveres skal være elevens selvstændigt udviklede produkt og dokumentation, hvor man på normal vis anvender internettet som et værktøj til at bibringe forståelse.&lt;br /&gt;
&lt;br /&gt;
==Problemet med ChatGPT==&lt;br /&gt;
Ligesom man ikke kan kilde-henvise til &amp;quot;google&amp;quot;, for at angive at man har fundet informationer på nettet, så kan man heller ikke kildehenvise til ChatGPT direkte som en kilde.&lt;br /&gt;
&lt;br /&gt;
Når man finder informationer med google&#039;, så skal man angive hvor på nettet man har fundet dem med så præcis en kildehenvisning, at man kan se den information der er blevet anvendt.&lt;br /&gt;
&lt;br /&gt;
Denne type henvisning kan man ikke lave i forhold til ChatGPT, da sprogmodellen der ligger bag ChatGPT konstant udvikler sig, samt at de svar sprogmodellen giver har et randomiseret element indbygget, som er med til at give bedre svar&amp;lt;ref&amp;gt;[https://www.it-vest.dk/arrangementer/sig-webinar-14-marts-2024-kunstig-intelligens-og-chatgpt-hvordan-virker-det-og-skal-vi-bare-opgive-undervisning-og-eksamen Webinar om kunstig intelligens]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Her er man altså nødt til at tage andre metoder i brug, for at kunne dokumentere at man har udviklet sit produkt ordentligt og redeligt.&lt;br /&gt;
&lt;br /&gt;
==Kildehenvisninger i dokumentation==&lt;br /&gt;
Der kan være forskellige standarder for hvordan man kildehenviser i forskellige uddannelser, dette er skrevet med udgangspunkt i at man anvender Word bibliografi-værktøj og her vist med en Harvard-lignende standard&amp;lt;ref&amp;gt;[https://holstebro-htx.dk/index.php/Word_Kildeliste Kildelister] anvendt i Microsoft Word&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Normal Internet-kilde til kode===&lt;br /&gt;
I dette eksempel er der angivet hvordan man ville dokumentere at man har anvendt kode fra et bibliotek til noget hardware på en [[Arduino]]. I det tænkte eksempel er det en 4 kanals AD-konverter&amp;lt;ref&amp;gt;[https://arduinotech.dk/shop/ads1115-module-4-channel-16-bit-i2c-adc-with-pro-gain-amplifier 4 kanals AD-konverter] fra ArduinoTech&amp;lt;/ref&amp;gt;, der er købt som modul.&lt;br /&gt;
&lt;br /&gt;
For at kunne anvende modulet i koden skal der kommunikeres med modulet på en måde, som er angivet i beskrivelsen af modulet - det er dog ikke nødvendigt at sætte sig ind i den grundlæggende kommunikation, hvis man blot ønsker at få værdier ind i sin software. Som en dokumentation for hvordan man anvender biblioteket kan man skrive følgende:&lt;br /&gt;
&lt;br /&gt;
====Eksempel på dokumentation====&lt;br /&gt;
Til at hente værdierne fra den 4 kanals AD-konverter anvendes et bibliotek fundet på GitHub (Singh, 2018) som kan indlæse de analoge spændinger.&lt;br /&gt;
Til at sætte AD-konverteren rigtigt op, til at kunne læse 4 spændinger, så anvendes eksemplet ”ADS1115_SingleEnded.ino” og i setup skrives følgende kode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
    ads.getAddr_ADS1115(ADS1115_DEFAULT_ADDRESS);   // 0x48, 1001 000 (ADDR = GND)&lt;br /&gt;
    ads.setGain(GAIN_TWO);          // 2x gain   +/- 2.048V  1 bit = 0.0625mV (default)&lt;br /&gt;
    ads.setMode(MODE_CONTIN);       // Continuous conversion mode&lt;br /&gt;
    ads.setRate(RATE_128);          // 128SPS (default)&lt;br /&gt;
    ads.setOSMode(OSMODE_SINGLE);   // Set to start a single-conversion&lt;br /&gt;
    ads.begin();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
I [[loop()]] testes i første omgang, om det kan lade sig gøre at læse de 4 kanaler. Dette gøres ved at afvikle følgende testkode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
    address = ads.ads_i2cAddress;&lt;br /&gt;
    Wire.beginTransmission(address);&lt;br /&gt;
    error = Wire.endTransmission();&lt;br /&gt;
    if (error == 0)&lt;br /&gt;
    {&lt;br /&gt;
        int16_t adc0, adc1, adc2, adc3;&lt;br /&gt;
&lt;br /&gt;
        adc0 = ads.Measure_SingleEnded(0);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 1: &amp;quot;);&lt;br /&gt;
        Serial.println(adc0);&lt;br /&gt;
        adc1 = ads.Measure_SingleEnded(1);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 2: &amp;quot;);&lt;br /&gt;
        Serial.println(adc1);&lt;br /&gt;
        adc2 = ads.Measure_SingleEnded(2);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 3: &amp;quot;);&lt;br /&gt;
        Serial.println(adc2);&lt;br /&gt;
        adc3 = ads.Measure_SingleEnded(3);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 4: &amp;quot;);&lt;br /&gt;
        Serial.println(adc3);&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Denne test giver det ønskede resultat.&lt;br /&gt;
&lt;br /&gt;
Ud fra denne beskrivelse viser man, at man tager andres kode, og anvender ind i sit eget projekt, og man angiver præcist i sin beskrivelse hvad man har taget fra andres kode.&lt;br /&gt;
&lt;br /&gt;
I kildelisten vil kilden optræde på følgende måde:&lt;br /&gt;
&lt;br /&gt;
: Singh, Y., 2018. Arduino Library ADS1115 16 bit 4 channel ADC. [Online] &amp;lt;br /&amp;gt;&lt;br /&gt;
: Available at: https://github.com/ncdcommunity/Arduino_Library_ADS1115_16Bit_4Channel_ADC&amp;lt;br /&amp;gt;&lt;br /&gt;
: [Senest hentet eller vist den 15 marts 2024].&lt;br /&gt;
&lt;br /&gt;
===ChatGPT som kilde til kode===&lt;br /&gt;
Det følgende er skrevet med udgangspunkt i det der er beskrevet på viden.ai&amp;lt;ref&amp;gt;[https://viden.ai/korrekt-kildehenvisning-af-chatgpt/ Korrekt kildehenvisning af ChatGPT]&amp;lt;/ref&amp;gt;. hvor der angives hvordan man kildehenviser, men også lidt om hvordan man håndterer det i tekst - i korte træk, lav et metodeafsnit, beskriv hvad man gør og vær meget redelig, ved at man angiver hvad man har fået af ChatGPT ved at lægge det ved som et bilag.&lt;br /&gt;
&lt;br /&gt;
Hvis man forstår at prompte fornuftigt, så er ChatGPT faktisk ret god til at foreslå kode, der kan anvendes, men ligesom det er plagiat hvis man kopierer fra nettet, så er det plagiat, hvis man lader ChatGPT skrive store dele af ens program for sig.&lt;br /&gt;
&lt;br /&gt;
Som det er formuleret i vejledningen til både programmering C og B, så kan man anvende ChatGPT til hjælp i fejlfinding af kode. For at kunne kildehenvise korrekt til hjælp med fejlfinding, så skal man angive hvad man har promptet til ChatGPT og hvad den har svaret - det kan placeres i bilag.&lt;br /&gt;
&lt;br /&gt;
En anden ting, som også er OK at få hjælp med er, at komme i gang med programmet - det er denne problematik der her gives et eksempel på. I eksemplet beskrives hvad man skal skrive i sin dokumentation, når man har anvendt denne hjælp, og der er forslag til hvordan man kommer videre i projektet.&lt;br /&gt;
&lt;br /&gt;
Konkret er det starten på udviklingen af et lille spil med bolde i et vindue, udviklet i Processing, der tages udgangspunkt i.&lt;br /&gt;
&lt;br /&gt;
====Metodeafsnit med omtale af ChatGPT====&lt;br /&gt;
Når man anvender CharGPT, så skal man dokumentere hvordan man har gjort det, og hvilke overvejelser der ligger bag det. Det betegnes i rapportskrivning som et metodeafsnit. Det kunne i dette eksempel lyde:&lt;br /&gt;
&lt;br /&gt;
For at få en fornuftig start på programkoden er der brugt ChatGPT til at få rammerne på koden etableret, og til at få et system, så der kan optræde flere bolde i programvinduet. Det er ChatGPT 3.5 (OpenAI, 2023)&amp;lt;ref&amp;gt;[https://chat.openai.com/chat Indgangen til ChatGPT 3.5]&amp;lt;/ref&amp;gt; der er anvendt til denne hjælp. Til programstarten blev der promptet efter at få et programvindue på 800x600 hvor en bold bevæger sig rundt. Den foreslåede kode blev kopieret ind i processings IDE (Processing, 2024)&amp;lt;ref&amp;gt;[https://processing.org Hovedsiden for Processing]&amp;lt;/ref&amp;gt; og testet – den opførte sig som forventet.&lt;br /&gt;
&lt;br /&gt;
Derefter blev der promptet efter at få den bold der bevægede sig til at dele sig op i to, når man klikker på den med musen. Dette resulterede i en væsentligt anderledes kode, som igen blev kopieret ind i processing og testet, og igen med et acceptabelt resultat. Dialogen med ChatGPT (OpenAI, 2023) og herunder de to koder, kan ses i bilag 1.&lt;br /&gt;
&lt;br /&gt;
Herefter er resten af koden udviklet på traditionel vis, hvor første trin var at dokumentere princippet i den foreslåede kode, specielt den Ball klasse der blev introduceret for at kunne arbejde med flere bolde i vinduet.&lt;br /&gt;
&lt;br /&gt;
Det nævnte bilag 1 [[media:ChatGPT-dialog-1.pdf|kan ses i denne PDF]].&lt;br /&gt;
&lt;br /&gt;
Når man opretter kilden i Word, så er det lidt forskelligt hvilke felter der er synlige, alt efter hvilken standard man har aktiv - men ved Harvard-Anglia standarden kan indtastningerne se således ud:&lt;br /&gt;
&lt;br /&gt;
[[fil:citat-ChatGPT.png|Indtastningerne ved kildehenvisning til ChatGPT|600px]]&amp;lt;br /&amp;gt;&#039;&#039;Indtastningerne ved kildehenvisning til ChatGPT&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Mere om teknikken i at anvende kildelister kan ses på [https://holstebro-htx.dk/index.php/Word_Kildeliste Holstebro HTX Wiki - Kildelister].&lt;br /&gt;
&lt;br /&gt;
====Dokumentation af koden udviklet af ChatGPT====&lt;br /&gt;
Da der skulle kunne dannes nye bolde så oprettes der en klasse, som ChatGPT skriver det i dialogen i Bilag 1:&lt;br /&gt;
&lt;br /&gt;
: &#039;&#039;&amp;quot;Dette kodeeksempel opretter en klasse kaldet Ball, som repræsenterer boldobjekterne. Når musen klikkes, kontrolleres det, om musens position er inden for en bold. Hvis det er tilfældet, oprettes to nye boldobjekter, der bevæger sig i forskellige retninger, og den originale bold fjernes fra arrayet.&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Ved at teste koden kan man se at det ikke er det helt rigtige den formulerer - der oprettes godt nok to nye bold-objekter, men det er ikke den oprindelige bold der fjernes, det er den ene af de ny-oprettede bolde. Det kan ses ved at de to bolde kommer i samme position, og den ene fortsætter i samme retning (den oprindelige), mens den ny-oprettede går i en tilfældig retning. Dette rettes til senere i dokumentationen under &amp;quot;oprettelse af ny bold&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
For at have en god struktur i koden, så placeres klassen Ball i en fil for sig kaldet Ball. Denne fil starter med at definere koden som en klasse med linjen:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
class Ball {&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dernæst defineres klassens egenskaber, der er boldens position og hastighed samt en fast diameter. Ud over det er der en x- og y-retning defineret. Den anvendes til at sige om bolden bevæger sig i en positiv eller negativ retning, så de skifter mellem +1 og -1, når kanterne rammes.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  float x, y;&lt;br /&gt;
  float xspeed, yspeed;&lt;br /&gt;
  int diameter = 30;&lt;br /&gt;
  int xdirection = 1;&lt;br /&gt;
  int ydirection = 1;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der defineres to forskellige constructors til bolden. Den første anvendes til at danne den første bold med, hvor position og hastighed sættes tilfældigt.&lt;br /&gt;
&lt;br /&gt;
Her forudses et problem at der kan komme et randfænomen, hvis bolden dannes, så den ligger med noget uden for skærmen. Da det er tilfældigt; så er det sjældent problemet opstår. For at fremprovokere det oftere er det testet med en diameter på 200, hvor det kunne ses at bolden bliver &amp;quot;hængende&amp;quot; i kanten.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  Ball() {&lt;br /&gt;
    x = random(width);&lt;br /&gt;
    y = random(height);&lt;br /&gt;
    xspeed = random(0.5, 2);&lt;br /&gt;
    yspeed = random(0.5, 2);&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Dette rettes ved at omskrive den foreslåede constructor til følgende kode, hvor bolden placeres mindst en halv diameter fra kanten:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  Ball() {&lt;br /&gt;
    x = random(diameter / 2, width - diameter / 2);&lt;br /&gt;
    y = random(diameter / 2, height - diameter / 2);&lt;br /&gt;
    xspeed = random(0.5, 2);&lt;br /&gt;
    yspeed = random(0.5, 2);&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Den anden constructor tager fire parametre, der er positionen og hastigheden. Denne constructor anvendes, når der skal dannes nye bolde, hvor koden netop skal starte den nye bold i den oprindelige bolds position, og med en ny retning.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  Ball(float x, float y, float xspeed, float yspeed) {&lt;br /&gt;
    this.x = x;&lt;br /&gt;
    this.y = y;&lt;br /&gt;
    this.xspeed = xspeed;&lt;br /&gt;
    this.yspeed = yspeed;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ud over disse standard ting til oprettelsen af objekter, så er der 3 metoder i klassen. Den første er en move() metode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  void move() {&lt;br /&gt;
    x = x + (xspeed * xdirection);&lt;br /&gt;
    y = y + (yspeed * ydirection);&lt;br /&gt;
&lt;br /&gt;
    if ((x + diameter/2 &amp;gt;= width) || (x - diameter/2 &amp;lt;= 0)) {&lt;br /&gt;
      xdirection *= -1;&lt;br /&gt;
    }&lt;br /&gt;
    if ((y + diameter/2 &amp;gt;= height) || (y - diameter/2 &amp;lt;= 0)) {&lt;br /&gt;
      ydirection *= -1;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Måden metoden virker på er at den lægger hastigheden til boldens position (både x og y), og hvis boldens position (både i x og y) er kommet uden for rammen, så ændres retningen for enten x eller y.&lt;br /&gt;
&lt;br /&gt;
For at kunne vise bolden er der en display() metode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  void display() {&lt;br /&gt;
    ellipse(x, y, diameter, diameter);&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Den sidste metode hedder contains(), og den tager en position som parameter til metoden. Der undersøges så om den position ligger inden for bolden ved at se om afstanden mellem boldens center og den testede position er mindre end den halve diameter. Hvis den er inden for bolden, så returneres true, ellers returneres false:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  boolean contains(float x, float y) {&lt;br /&gt;
    float d = dist(x, y, this.x, this.y);&lt;br /&gt;
    if (d &amp;lt; diameter/2) {&lt;br /&gt;
      return true;&lt;br /&gt;
    } else {&lt;br /&gt;
      return false;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Oprettelse af ny bold====&lt;br /&gt;
I den oprindelige kode undersøges om der er klikket på en bold, ved at alle bolde løbes igennem i mousePressed() funktionen, og med metoden contains undersøges om der er klikket på en bold. Denne måde at undersøge alle bolde på beholdes.&lt;br /&gt;
&lt;br /&gt;
Som omtalt er det ikke den smarteste måde til at dele bolden op i to, der anvendes. Som det ses i koden herunder, så appendes der to nye bolde på med den oprindelige bolds x- og y-position på samt tilfældige x- og y-hastigheder. Disse to bolde lægges i slutningen af arrayet. Derefter anvendes shorten&amp;lt;ref&amp;gt;[https://processing.org/reference/shorten_.html Processings shorten metode til arrays]&amp;lt;/ref&amp;gt; til at fjerne et element, men da det element der fjernes er det sidste element i arrayet, så fjernes der bare den sidst oprettede bold.&lt;br /&gt;
&lt;br /&gt;
Hvis man var tilfreds med den opførsel, så kunne man blot fjerne kodelinjen med den anden append og kodelinjen med shorten. Så ville man have samme funktion.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
    if (balls[i].contains(mouseX, mouseY)) {&lt;br /&gt;
      balls = (Ball[]) append(balls, new Ball(balls[i].x, balls[i].y, random(-5, 5), random(-5, 5)));&lt;br /&gt;
      balls = (Ball[]) append(balls, new Ball(balls[i].x, balls[i].y, random(-5, 5), random(-5, 5)));&lt;br /&gt;
      balls = (Ball[]) shorten(balls);&lt;br /&gt;
      break;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Den nye bold der oprettes får bare en tilfældig retning, og den oprindelige bold fortsætter bare i den retning den var på vej i. Det er ikke den opførsel der ønskes i spillet. Der ønskes i stedet at det ser ud som om bolden &amp;quot;splittes op&amp;quot; i 2 bolde, og den opførsel laves ved at lade den oprindelige bold ændre 30 grader til den ene side, og den nye bold får 30 grader til den anden side.&lt;br /&gt;
&lt;br /&gt;
For at gøre dette, så oprettes der en metode multiply() i klassen Ball. Denne metode returnerer en ny bold af typen Ball, så nu kan koden i museklikket skrives som følger:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
    if (balls[i].contains(mouseX, mouseY)) {&lt;br /&gt;
      balls = (Ball[]) append(balls, balls[i].multiply());&lt;br /&gt;
      break;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Som det kan ses, så appendes der en ny bold ind i balls-arrayet, ud fra metoden multiply().&lt;br /&gt;
&lt;br /&gt;
Metoden multiply() oprettes inde i klassen med følgende kode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  Ball multiply() {&lt;br /&gt;
    xspeed *= xdirection;&lt;br /&gt;
    yspeed *= ydirection;&lt;br /&gt;
    xdirection = 1;&lt;br /&gt;
    ydirection = 1;&lt;br /&gt;
    float speed = dist(0, 0, xspeed, yspeed);&lt;br /&gt;
    float angle = acos(xspeed / speed);&lt;br /&gt;
    if (yspeed &amp;lt; 0) angle = 0.0 - angle;&lt;br /&gt;
    speed *= 1.5;&lt;br /&gt;
    xspeed = speed * cos(angle + PI / 6);&lt;br /&gt;
    yspeed = speed * sin(angle + PI / 6);&lt;br /&gt;
    Ball b = new Ball(x, y, speed * cos(angle - PI / 6), speed * sin(angle - PI / 6));&lt;br /&gt;
    return b;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Først regnes retningen over i xspeed og yspeed, så de kan være både positive og negative. På den måde indeholder de to variabler retningen.&lt;br /&gt;
&lt;br /&gt;
Dernæst omregnes x- og y-hastigheden til en samlet hastighed speed og en vinkel angle, som kan være mellem +PI og -PI (+/- 180 grader).&lt;br /&gt;
&lt;br /&gt;
Begge bolde skal bevæge sig hurtigere efter de er delt, så spillet gradvist bliver sværere, derfor ganges hastigheden med 1,5.&lt;br /&gt;
&lt;br /&gt;
Den oprindelige bold får nu en ny retning, ved at udregne x- og y-hastigheden ud fra den nye hastighed og vinklen plus 30 grader.&lt;br /&gt;
&lt;br /&gt;
Til sidst oprettes en ny bold med samme position som den oprindelige og en x- og y-hastighed udregnet fra den oprindelige bolds hastighed og vinklen minus 30 grader. Denne bold returneres fra metoden.&lt;br /&gt;
&lt;br /&gt;
==Refleksioner over anvendelsen==&lt;br /&gt;
Der er selvfølgelig stadig lang vej til man har et færdigt spil, men ideen var også at tage fat i, hvordan man anvender ChatGPT på en ordentlig og redelig måde i et programmeringsprojekt. Dette kan selvfølgelig altid gradbøjes, men hvis man håndterer anvendelsen som vist i eksemplet, så vil man ikke gøre noget der kommer i nærheden af plagiat.&lt;br /&gt;
&lt;br /&gt;
==Referencer== &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt; &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Programmering}}&lt;br /&gt;
&lt;br /&gt;
[[Kategori:Programmering teknik]]&lt;/div&gt;</summary>
		<author><name>Bar</name></author>
	</entry>
	<entry>
		<id>https://www.htxarduino.dk/index.php?title=Programmering_med_ChatGPT&amp;diff=5407</id>
		<title>Programmering med ChatGPT</title>
		<link rel="alternate" type="text/html" href="https://www.htxarduino.dk/index.php?title=Programmering_med_ChatGPT&amp;diff=5407"/>
		<updated>2024-03-20T10:08:13Z</updated>

		<summary type="html">&lt;p&gt;Bar: /* Eksempel på dokumentation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Det er ikke så svært at få ChatGPT&amp;lt;ref&amp;gt;[https://chat.openai.com/auth/login ChatGPT Login] - Indgangen til ChatGPT&amp;lt;/ref&amp;gt; til at lave kode, der skal man blot beskrive hvad man gerne vil have programmet til at gøre, og så kopiere den kode, der kommer ud af det - det giver tit ret gode resultater.&lt;br /&gt;
&lt;br /&gt;
Problemet med at anvende ChatGPT i forbindelse med skoleprojekter er, at man skal have forståelsen med i det, og at man ikke kan blive anklaget for plagiat.&lt;br /&gt;
&lt;br /&gt;
==Hvad må man ikke i et skoleprojekt==&lt;br /&gt;
*Man må ikke kopiere kode, som man ikke selv har skrevet, til et programmeringsprodukt uden at man angiver en kilde. Det er uanset hvor koden stammer fra, også selvom man har brugt ChatGPT til at &amp;quot;udvikle&amp;quot; koden.&lt;br /&gt;
*Man må ikke aflevere et produkt hvor de primære dele af koden er kopieret, heller ikke selvom man kildehenviser.&lt;br /&gt;
*Man må ikke få ChatGPT til at dokumentere sin kode, ved at man kopierer ChatGPT&#039;s beskrivelse ind i sin dokumentation af koden.&lt;br /&gt;
&lt;br /&gt;
De beskrevne eksempler er at betragte som plagiat, og vil blive håndteret efter skolens ordensregler, hvilket i værste fald kan ende med at et fag annulleres eller man bliver bortvist fra uddannelsen.&lt;br /&gt;
&lt;br /&gt;
==Hvad er tilladt med ChatGPT==&lt;br /&gt;
På samme måde som man må anvende kilder fra internettet, så må man i programmerings-faget i gymnasiet anvende ChatGPT i udviklingen af kode til et programmeringsprodukt. Dette er blevet tilladt via en revidering af vejledningen til faget&amp;lt;ref&amp;gt;[https://www.uvm.dk/-/media/filer/uvm/udd/gym/pdf23/aug/vejledninger/valgfag/230807-programmering-c--valgfag.pdf Vejledning] til Valgfaget Programmering C&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
I vejledningen står der som følger:&lt;br /&gt;
&lt;br /&gt;
: &#039;&#039;&amp;quot;brug af internettet er tilladt som fagligt hjælpemiddel ved de mundtlige prøver, inkluderer de tilladte hjælpemidler anvendelsen af chatbots og lignende på en måde, som afspejler, hvordan man arbejder i den daglige undervisning. Dette kunne fx være brug af ChatGPT til at debugge kode.&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Det skal altså afspejle den normale brug, som man også har ved at bruge internettet. Som angivet under hvad man ikke må, så er den normale brug, at man anvender information til at lære at programmere, men at man ikke tager så meget af sit produkt fra nettet, så man ikke har en forståelse af hvordan produktet er sammensat.&lt;br /&gt;
&lt;br /&gt;
Videre i vejledningen står der:&lt;br /&gt;
&lt;br /&gt;
: &#039;&#039;&amp;quot;I forhold til denne type hjælpemidler er det vigtigt at være opmærksom på, at den tilladte anvendelse er betinget af, at hjælpemidlerne kun benyttes i et omfang, hvor prøvebesvarelsen er selvstændig og udelukkende elevens egen.&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Igen understreges at det der afleveres skal være elevens selvstændigt udviklede produkt og dokumentation, hvor man på normal vis anvender internettet som et værktøj til at bibringe forståelse.&lt;br /&gt;
&lt;br /&gt;
==Problemet med ChatGPT==&lt;br /&gt;
Ligesom man ikke kan kilde-henvise til &amp;quot;google&amp;quot;, for at angive at man har fundet informationer på nettet, så kan man heller ikke kildehenvise til ChatGPT direkte som en kilde.&lt;br /&gt;
&lt;br /&gt;
Når man finder informationer med google&#039;, så skal man angive hvor på nettet man har fundet dem med så præcis en kildehenvisning, at man kan se den information der er blevet anvendt.&lt;br /&gt;
&lt;br /&gt;
Denne type henvisning kan man ikke lave i forhold til ChatGPT, da sprogmodellen der ligger bag ChatGPT konstant udvikler sig, samt at de svar sprogmodellen giver har et randomiseret element indbygget, som er med til at give bedre svar&amp;lt;ref&amp;gt;[https://www.it-vest.dk/arrangementer/sig-webinar-14-marts-2024-kunstig-intelligens-og-chatgpt-hvordan-virker-det-og-skal-vi-bare-opgive-undervisning-og-eksamen Webinar om kunstig intelligens]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Her er man altså nødt til at tage andre metoder i brug, for at kunne dokumentere at man har udviklet sit produkt ordentligt og redeligt.&lt;br /&gt;
&lt;br /&gt;
==Kildehenvisninger i dokumentation==&lt;br /&gt;
Der kan være forskellige standarder for hvordan man kildehenviser i forskellige uddannelser, dette er skrevet med udgangspunkt i at man anvender Word bibliografi-værktøj og her vist med en Harvard-lignende standard&amp;lt;ref&amp;gt;[https://holstebro-htx.dk/index.php/Word_Kildeliste Kildelister] anvendt i Microsoft Word&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Normal Internet-kilde til kode===&lt;br /&gt;
I dette eksempel er der angivet hvordan man ville dokumentere at man har anvendt kode fra et bibliotek til noget hardware på en [[Arduino]]. I det tænkte eksempel er det en 4 kanals AD-konverter&amp;lt;ref&amp;gt;[https://arduinotech.dk/shop/ads1115-module-4-channel-16-bit-i2c-adc-with-pro-gain-amplifier 4 kanals AD-konverter] fra ArduinoTech&amp;lt;/ref&amp;gt;, der er købt som modul.&lt;br /&gt;
&lt;br /&gt;
For at kunne anvende modulet i koden skal der kommunikeres med modulet på en måde, som er angivet i beskrivelsen af modulet - det er dog ikke nødvendigt at sætte sig ind i den grundlæggende kommunikation, hvis man blot ønsker at få værdier ind i sin software. Som en dokumentation for hvordan man anvender biblioteket kan man skrive følgende:&lt;br /&gt;
&lt;br /&gt;
====Eksempel på dokumentation====&lt;br /&gt;
Til at hente værdierne fra den 4 kanals AD-konverter anvendes et bibliotek fundet på GitHub (Singh, 2018) som kan indlæse de analoge spændinger.&lt;br /&gt;
Til at sætte AD-konverteren rigtigt op, til at kunne læse 4 spændinger, så anvendes eksemplet ”ADS1115_SingleEnded.ino” og i setup skrives følgende kode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
    ads.getAddr_ADS1115(ADS1115_DEFAULT_ADDRESS);   // 0x48, 1001 000 (ADDR = GND)&lt;br /&gt;
    ads.setGain(GAIN_TWO);          // 2x gain   +/- 2.048V  1 bit = 0.0625mV (default)&lt;br /&gt;
    ads.setMode(MODE_CONTIN);       // Continuous conversion mode&lt;br /&gt;
    ads.setRate(RATE_128);          // 128SPS (default)&lt;br /&gt;
    ads.setOSMode(OSMODE_SINGLE);   // Set to start a single-conversion&lt;br /&gt;
    ads.begin();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
I [[loop()]] testes i første omgang, om det kan lade sig gøre at læse de 4 kanaler. Dette gøres ved at afvikle følgende testkode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
    address = ads.ads_i2cAddress;&lt;br /&gt;
    Wire.beginTransmission(address);&lt;br /&gt;
    error = Wire.endTransmission();&lt;br /&gt;
    if (error == 0)&lt;br /&gt;
    {&lt;br /&gt;
        int16_t adc0, adc1, adc2, adc3;&lt;br /&gt;
&lt;br /&gt;
        adc0 = ads.Measure_SingleEnded(0);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 1: &amp;quot;);&lt;br /&gt;
        Serial.println(adc0);&lt;br /&gt;
        adc1 = ads.Measure_SingleEnded(1);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 2: &amp;quot;);&lt;br /&gt;
        Serial.println(adc1);&lt;br /&gt;
        adc2 = ads.Measure_SingleEnded(2);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 3: &amp;quot;);&lt;br /&gt;
        Serial.println(adc2);&lt;br /&gt;
        adc3 = ads.Measure_SingleEnded(3);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 4: &amp;quot;);&lt;br /&gt;
        Serial.println(adc3);&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Denne test giver det ønskede resultat.&lt;br /&gt;
&lt;br /&gt;
Ud fra denne beskrivelse viser man, at man tager andres kode, og anvender ind i sit eget projekt, og man angiver præcist i sin beskrivelse hvad man har taget fra andres kode.&lt;br /&gt;
&lt;br /&gt;
I kildelisten vil kilden optræde på følgende måde:&lt;br /&gt;
&lt;br /&gt;
: Singh, Y., 2018. Arduino Library ADS1115 16 bit 4 channel ADC. [Online] &amp;lt;br /&amp;gt;&lt;br /&gt;
: Available at: https://github.com/ncdcommunity/Arduino_Library_ADS1115_16Bit_4Channel_ADC&amp;lt;br /&amp;gt;&lt;br /&gt;
: [Senest hentet eller vist den 15 marts 2024].&lt;br /&gt;
&lt;br /&gt;
===ChatGPT som kilde til kode===&lt;br /&gt;
Det følgende er skrevet med udgangspunkt i det der er beskrevet på viden.ai&amp;lt;ref&amp;gt;[https://viden.ai/korrekt-kildehenvisning-af-chatgpt/ Korrekt kildehenvisning af ChatGPT]&amp;lt;/ref&amp;gt;. hvor der angives hvordan man kildehenviser, men også lidt om hvordan man håndterer det i tekst - i korte træk, lav et metodeafsnit, beskriv hvad man gør og vær meget redelig, ved at man angiver hvad man har fået af ChatGPT ved at lægge det ved som et bilag.&lt;br /&gt;
&lt;br /&gt;
Hvis man forstår at prompte fornuftigt, så er ChatGPT faktisk ret god til at foreslå kode, der kan anvendes, men ligesom det er plagiat hvis man kopierer fra nettet, så er det plagiat, hvis man lader ChatGPT skrive store dele af ens program for sig.&lt;br /&gt;
&lt;br /&gt;
Som det er formuleret i vejledningen til både programmering C og B, så kan man anvende ChatGPT til hjælp i fejlfinding af kode. For at kunne kildehenvise korrekt til hjælp med fejlfinding, så skal man angive hvad man har promptet til ChatGPT og hvad den har svaret - det kan placeres i bilag.&lt;br /&gt;
&lt;br /&gt;
En anden ting, som også er OK at få hjælp med er, at komme i gang med programmet - det er denne problematik der her gives et eksempel på. I eksemplet beskrives hvad man skal skrive i sin dokumentation, når man har anvendt denne hjælp, og der er forslag til hvordan man kommer videre i projektet.&lt;br /&gt;
&lt;br /&gt;
Konkret er det starten på udviklingen af et lille spil med bolde i et vindue, udviklet i Processing, der tages udgangspunkt i.&lt;br /&gt;
&lt;br /&gt;
====Metodeafsnit med omtale af ChatGPT====&lt;br /&gt;
Når man anvender CharGPT, så skal man dokumentere hvordan man har gjort det, og hvilke overvejelser der ligger bag det. Det betegnes i rapportskrivning som et metodeafsnit. Det kunne i dette eksempel lyde:&lt;br /&gt;
&lt;br /&gt;
For at få en fornuftig start på programkoden er der brugt ChatGPT til at få rammerne på koden etableret, og til at få et system, så der kan optræde flere bolde i programvinduet. Det er ChatGPT 3.5 (OpenAI, 2023)&amp;lt;ref&amp;gt;[https://chat.openai.com/chat Indgangen til ChatGPT 3.5]&amp;lt;/ref&amp;gt; der er anvendt til denne hjælp. Til programstarten blev der promptet efter at få et programvindue på 800x600 hvor en bold bevæger sig rundt. Den foreslåede kode blev kopieret ind i processings IDE (Processing, 2024)&amp;lt;ref&amp;gt;[https://processing.org Hovedsiden for Processing]&amp;lt;/ref&amp;gt; og testet – den opførte sig som forventet.&lt;br /&gt;
&lt;br /&gt;
Derefter blev der promptet efter at få den bold der bevægede sig til at dele sig op i to, når man klikker på den med musen. Dette resulterede i en væsentligt anderledes kode, som igen blev kopieret ind i processing og testet, og igen med et acceptabelt resultat. Dialogen med ChatGPT (OpenAI, 2023) og herunder de to koder, kan ses i bilag 1.&lt;br /&gt;
&lt;br /&gt;
Herefter er resten af koden udviklet på traditionel vis, hvor første trin var at dokumentere princippet i den foreslåede kode, specielt den Ball klasse der blev introduceret for at kunne arbejde med flere bolde i vinduet.&lt;br /&gt;
&lt;br /&gt;
Det nævnte bilag 1 [[media:ChatGPT-dialog-1.pdf|kan ses i denne PDF]].&lt;br /&gt;
&lt;br /&gt;
Når man opretter kilden i Word, så er det lidt forskelligt hvilke felter der er synlige, alt efter hvilken standard man har aktiv - men ved Harvard standarden kan indtastningerne se således ud:&lt;br /&gt;
&lt;br /&gt;
[[fil:citat-ChatGPT.png|Indtastningerne ved kildehenvisning til ChatGPT|600px]]&amp;lt;br /&amp;gt;&#039;&#039;Indtastningerne ved kildehenvisning til ChatGPT&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Mere om teknikken i at anvende kildelister kan ses på [https://holstebro-htx.dk/index.php/Word_Kildeliste Holstebro HTX Wiki - Kildelister].&lt;br /&gt;
&lt;br /&gt;
====Dokumentation af koden udviklet af ChatGPT====&lt;br /&gt;
Da der skulle kunne dannes nye bolde så oprettes der en klasse, som ChatGPT skriver det i dialogen i Bilag 1:&lt;br /&gt;
&lt;br /&gt;
: &#039;&#039;&amp;quot;Dette kodeeksempel opretter en klasse kaldet Ball, som repræsenterer boldobjekterne. Når musen klikkes, kontrolleres det, om musens position er inden for en bold. Hvis det er tilfældet, oprettes to nye boldobjekter, der bevæger sig i forskellige retninger, og den originale bold fjernes fra arrayet.&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Ved at teste koden kan man se at det ikke er det helt rigtige den formulerer - der oprettes godt nok to nye bold-objekter, men det er ikke den oprindelige bold der fjernes, det er den ene af de ny-oprettede bolde. Det kan ses ved at de to bolde kommer i samme position, og den ene fortsætter i samme retning (den oprindelige), mens den ny-oprettede går i en tilfældig retning. Dette rettes til senere i dokumentationen under &amp;quot;oprettelse af ny bold&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
For at have en god struktur i koden, så placeres klassen Ball i en fil for sig kaldet Ball. Denne fil starter med at definere koden som en klasse med linjen:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
class Ball {&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dernæst defineres klassens egenskaber, der er boldens position og hastighed samt en fast diameter. Ud over det er der en x- og y-retning defineret. Den anvendes til at sige om bolden bevæger sig i en positiv eller negativ retning, så de skifter mellem +1 og -1, når kanterne rammes.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  float x, y;&lt;br /&gt;
  float xspeed, yspeed;&lt;br /&gt;
  int diameter = 30;&lt;br /&gt;
  int xdirection = 1;&lt;br /&gt;
  int ydirection = 1;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der defineres to forskellige constructors til bolden. Den første anvendes til at danne den første bold med, hvor position og hastighed sættes tilfældigt.&lt;br /&gt;
&lt;br /&gt;
Her forudses et problem at der kan komme et randfænomen, hvis bolden dannes, så den ligger med noget uden for skærmen. Da det er tilfældigt; så er det sjældent problemet opstår. For at fremprovokere det oftere er det testet med en diameter på 200, hvor det kunne ses at bolden bliver &amp;quot;hængende&amp;quot; i kanten.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  Ball() {&lt;br /&gt;
    x = random(width);&lt;br /&gt;
    y = random(height);&lt;br /&gt;
    xspeed = random(0.5, 2);&lt;br /&gt;
    yspeed = random(0.5, 2);&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Dette rettes ved at omskrive den foreslåede constructor til følgende kode, hvor bolden placeres mindst en halv diameter fra kanten:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  Ball() {&lt;br /&gt;
    x = random(diameter / 2, width - diameter / 2);&lt;br /&gt;
    y = random(diameter / 2, height - diameter / 2);&lt;br /&gt;
    xspeed = random(0.5, 2);&lt;br /&gt;
    yspeed = random(0.5, 2);&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Den anden constructor tager fire parametre, der er positionen og hastigheden. Denne constructor anvendes, når der skal dannes nye bolde, hvor koden netop skal starte den nye bold i den oprindelige bolds position, og med en ny retning.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  Ball(float x, float y, float xspeed, float yspeed) {&lt;br /&gt;
    this.x = x;&lt;br /&gt;
    this.y = y;&lt;br /&gt;
    this.xspeed = xspeed;&lt;br /&gt;
    this.yspeed = yspeed;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ud over disse standard ting til oprettelsen af objekter, så er der 3 metoder i klassen. Den første er en move() metode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  void move() {&lt;br /&gt;
    x = x + (xspeed * xdirection);&lt;br /&gt;
    y = y + (yspeed * ydirection);&lt;br /&gt;
&lt;br /&gt;
    if ((x + diameter/2 &amp;gt;= width) || (x - diameter/2 &amp;lt;= 0)) {&lt;br /&gt;
      xdirection *= -1;&lt;br /&gt;
    }&lt;br /&gt;
    if ((y + diameter/2 &amp;gt;= height) || (y - diameter/2 &amp;lt;= 0)) {&lt;br /&gt;
      ydirection *= -1;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Måden metoden virker på er at den lægger hastigheden til boldens position (både x og y), og hvis boldens position (både i x og y) er kommet uden for rammen, så ændres retningen for enten x eller y.&lt;br /&gt;
&lt;br /&gt;
For at kunne vise bolden er der en display() metode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  void display() {&lt;br /&gt;
    ellipse(x, y, diameter, diameter);&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Den sidste metode hedder contains(), og den tager en position som parameter til metoden. Der undersøges så om den position ligger inden for bolden ved at se om afstanden mellem boldens center og den testede position er mindre end den halve diameter. Hvis den er inden for bolden, så returneres true, ellers returneres false:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  boolean contains(float x, float y) {&lt;br /&gt;
    float d = dist(x, y, this.x, this.y);&lt;br /&gt;
    if (d &amp;lt; diameter/2) {&lt;br /&gt;
      return true;&lt;br /&gt;
    } else {&lt;br /&gt;
      return false;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Oprettelse af ny bold====&lt;br /&gt;
I den oprindelige kode undersøges om der er klikket på en bold, ved at alle bolde løbes igennem i mousePressed() funktionen, og med metoden contains undersøges om der er klikket på en bold. Denne måde at undersøge alle bolde på beholdes.&lt;br /&gt;
&lt;br /&gt;
Som omtalt er det ikke den smarteste måde til at dele bolden op i to, der anvendes. Som det ses i koden herunder, så appendes der to nye bolde på med den oprindelige bolds x- og y-position på samt tilfældige x- og y-hastigheder. Disse to bolde lægges i slutningen af arrayet. Derefter anvendes shorten&amp;lt;ref&amp;gt;[https://processing.org/reference/shorten_.html Processings shorten metode til arrays]&amp;lt;/ref&amp;gt; til at fjerne et element, men da det element der fjernes er det sidste element i arrayet, så fjernes der bare den sidst oprettede bold.&lt;br /&gt;
&lt;br /&gt;
Hvis man var tilfreds med den opførsel, så kunne man blot fjerne kodelinjen med den anden append og kodelinjen med shorten. Så ville man have samme funktion.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
    if (balls[i].contains(mouseX, mouseY)) {&lt;br /&gt;
      balls = (Ball[]) append(balls, new Ball(balls[i].x, balls[i].y, random(-5, 5), random(-5, 5)));&lt;br /&gt;
      balls = (Ball[]) append(balls, new Ball(balls[i].x, balls[i].y, random(-5, 5), random(-5, 5)));&lt;br /&gt;
      balls = (Ball[]) shorten(balls);&lt;br /&gt;
      break;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Den nye bold der oprettes får bare en tilfældig retning, og den oprindelige bold fortsætter bare i den retning den var på vej i. Det er ikke den opførsel der ønskes i spillet. Der ønskes i stedet at det ser ud som om bolden &amp;quot;splittes op&amp;quot; i 2 bolde, og den opførsel laves ved at lade den oprindelige bold ændre 30 grader til den ene side, og den nye bold får 30 grader til den anden side.&lt;br /&gt;
&lt;br /&gt;
For at gøre dette, så oprettes der en metode multiply() i klassen Ball. Denne metode returnerer en ny bold af typen Ball, så nu kan koden i museklikket skrives som følger:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
    if (balls[i].contains(mouseX, mouseY)) {&lt;br /&gt;
      balls = (Ball[]) append(balls, balls[i].multiply());&lt;br /&gt;
      break;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Som det kan ses, så appendes der en ny bold ind i balls-arrayet, ud fra metoden multiply().&lt;br /&gt;
&lt;br /&gt;
Metoden multiply() oprettes inde i klassen med følgende kode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  Ball multiply() {&lt;br /&gt;
    xspeed *= xdirection;&lt;br /&gt;
    yspeed *= ydirection;&lt;br /&gt;
    xdirection = 1;&lt;br /&gt;
    ydirection = 1;&lt;br /&gt;
    float speed = dist(0, 0, xspeed, yspeed);&lt;br /&gt;
    float angle = acos(xspeed / speed);&lt;br /&gt;
    if (yspeed &amp;lt; 0) angle = 0.0 - angle;&lt;br /&gt;
    speed *= 1.5;&lt;br /&gt;
    xspeed = speed * cos(angle + PI / 6);&lt;br /&gt;
    yspeed = speed * sin(angle + PI / 6);&lt;br /&gt;
    Ball b = new Ball(x, y, speed * cos(angle - PI / 6), speed * sin(angle - PI / 6));&lt;br /&gt;
    return b;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Først regnes retningen over i xspeed og yspeed, så de kan være både positive og negative. På den måde indeholder de to variabler retningen.&lt;br /&gt;
&lt;br /&gt;
Dernæst omregnes x- og y-hastigheden til en samlet hastighed speed og en vinkel angle, som kan være mellem +PI og -PI (+/- 180 grader).&lt;br /&gt;
&lt;br /&gt;
Begge bolde skal bevæge sig hurtigere efter de er delt, så spillet gradvist bliver sværere, derfor ganges hastigheden med 1,5.&lt;br /&gt;
&lt;br /&gt;
Den oprindelige bold får nu en ny retning, ved at udregne x- og y-hastigheden ud fra den nye hastighed og vinklen plus 30 grader.&lt;br /&gt;
&lt;br /&gt;
Til sidst oprettes en ny bold med samme position som den oprindelige og en x- og y-hastighed udregnet fra den oprindelige bolds hastighed og vinklen minus 30 grader. Denne bold returneres fra metoden.&lt;br /&gt;
&lt;br /&gt;
==Refleksioner over anvendelsen==&lt;br /&gt;
Der er selvfølgelig stadig lang vej til man har et færdigt spil, men ideen var også at tage fat i, hvordan man anvender ChatGPT på en ordentlig og redelig måde i et programmeringsprojekt. Dette kan selvfølgelig altid gradbøjes, men hvis man håndterer anvendelsen som vist i eksemplet, så vil man ikke gøre noget der kommer i nærheden af plagiat.&lt;br /&gt;
&lt;br /&gt;
==Referencer== &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt; &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Programmering}}&lt;br /&gt;
&lt;br /&gt;
[[Kategori:Programmering teknik]]&lt;/div&gt;</summary>
		<author><name>Bar</name></author>
	</entry>
	<entry>
		<id>https://www.htxarduino.dk/index.php?title=Programmering_med_ChatGPT&amp;diff=5406</id>
		<title>Programmering med ChatGPT</title>
		<link rel="alternate" type="text/html" href="https://www.htxarduino.dk/index.php?title=Programmering_med_ChatGPT&amp;diff=5406"/>
		<updated>2024-03-20T10:06:26Z</updated>

		<summary type="html">&lt;p&gt;Bar: /* Hvad må man ikke i en skoleprojekt */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Det er ikke så svært at få ChatGPT&amp;lt;ref&amp;gt;[https://chat.openai.com/auth/login ChatGPT Login] - Indgangen til ChatGPT&amp;lt;/ref&amp;gt; til at lave kode, der skal man blot beskrive hvad man gerne vil have programmet til at gøre, og så kopiere den kode, der kommer ud af det - det giver tit ret gode resultater.&lt;br /&gt;
&lt;br /&gt;
Problemet med at anvende ChatGPT i forbindelse med skoleprojekter er, at man skal have forståelsen med i det, og at man ikke kan blive anklaget for plagiat.&lt;br /&gt;
&lt;br /&gt;
==Hvad må man ikke i et skoleprojekt==&lt;br /&gt;
*Man må ikke kopiere kode, som man ikke selv har skrevet, til et programmeringsprodukt uden at man angiver en kilde. Det er uanset hvor koden stammer fra, også selvom man har brugt ChatGPT til at &amp;quot;udvikle&amp;quot; koden.&lt;br /&gt;
*Man må ikke aflevere et produkt hvor de primære dele af koden er kopieret, heller ikke selvom man kildehenviser.&lt;br /&gt;
*Man må ikke få ChatGPT til at dokumentere sin kode, ved at man kopierer ChatGPT&#039;s beskrivelse ind i sin dokumentation af koden.&lt;br /&gt;
&lt;br /&gt;
De beskrevne eksempler er at betragte som plagiat, og vil blive håndteret efter skolens ordensregler, hvilket i værste fald kan ende med at et fag annulleres eller man bliver bortvist fra uddannelsen.&lt;br /&gt;
&lt;br /&gt;
==Hvad er tilladt med ChatGPT==&lt;br /&gt;
På samme måde som man må anvende kilder fra internettet, så må man i programmerings-faget i gymnasiet anvende ChatGPT i udviklingen af kode til et programmeringsprodukt. Dette er blevet tilladt via en revidering af vejledningen til faget&amp;lt;ref&amp;gt;[https://www.uvm.dk/-/media/filer/uvm/udd/gym/pdf23/aug/vejledninger/valgfag/230807-programmering-c--valgfag.pdf Vejledning] til Valgfaget Programmering C&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
I vejledningen står der som følger:&lt;br /&gt;
&lt;br /&gt;
: &#039;&#039;&amp;quot;brug af internettet er tilladt som fagligt hjælpemiddel ved de mundtlige prøver, inkluderer de tilladte hjælpemidler anvendelsen af chatbots og lignende på en måde, som afspejler, hvordan man arbejder i den daglige undervisning. Dette kunne fx være brug af ChatGPT til at debugge kode.&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Det skal altså afspejle den normale brug, som man også har ved at bruge internettet. Som angivet under hvad man ikke må, så er den normale brug, at man anvender information til at lære at programmere, men at man ikke tager så meget af sit produkt fra nettet, så man ikke har en forståelse af hvordan produktet er sammensat.&lt;br /&gt;
&lt;br /&gt;
Videre i vejledningen står der:&lt;br /&gt;
&lt;br /&gt;
: &#039;&#039;&amp;quot;I forhold til denne type hjælpemidler er det vigtigt at være opmærksom på, at den tilladte anvendelse er betinget af, at hjælpemidlerne kun benyttes i et omfang, hvor prøvebesvarelsen er selvstændig og udelukkende elevens egen.&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Igen understreges at det der afleveres skal være elevens selvstændigt udviklede produkt og dokumentation, hvor man på normal vis anvender internettet som et værktøj til at bibringe forståelse.&lt;br /&gt;
&lt;br /&gt;
==Problemet med ChatGPT==&lt;br /&gt;
Ligesom man ikke kan kilde-henvise til &amp;quot;google&amp;quot;, for at angive at man har fundet informationer på nettet, så kan man heller ikke kildehenvise til ChatGPT direkte som en kilde.&lt;br /&gt;
&lt;br /&gt;
Når man finder informationer med google&#039;, så skal man angive hvor på nettet man har fundet dem med så præcis en kildehenvisning, at man kan se den information der er blevet anvendt.&lt;br /&gt;
&lt;br /&gt;
Denne type henvisning kan man ikke lave i forhold til ChatGPT, da sprogmodellen der ligger bag ChatGPT konstant udvikler sig, samt at de svar sprogmodellen giver har et randomiseret element indbygget, som er med til at give bedre svar&amp;lt;ref&amp;gt;[https://www.it-vest.dk/arrangementer/sig-webinar-14-marts-2024-kunstig-intelligens-og-chatgpt-hvordan-virker-det-og-skal-vi-bare-opgive-undervisning-og-eksamen Webinar om kunstig intelligens]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Her er man altså nødt til at tage andre metoder i brug, for at kunne dokumentere at man har udviklet sit produkt ordentligt og redeligt.&lt;br /&gt;
&lt;br /&gt;
==Kildehenvisninger i dokumentation==&lt;br /&gt;
Der kan være forskellige standarder for hvordan man kildehenviser i forskellige uddannelser, dette er skrevet med udgangspunkt i at man anvender Word bibliografi-værktøj og her vist med en Harvard-lignende standard&amp;lt;ref&amp;gt;[https://holstebro-htx.dk/index.php/Word_Kildeliste Kildelister] anvendt i Microsoft Word&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Normal Internet-kilde til kode===&lt;br /&gt;
I dette eksempel er der angivet hvordan man ville dokumentere at man har anvendt kode fra et bibliotek til noget hardware på en [[Arduino]]. I det tænkte eksempel er det en 4 kanals AD-konverter&amp;lt;ref&amp;gt;[https://arduinotech.dk/shop/ads1115-module-4-channel-16-bit-i2c-adc-with-pro-gain-amplifier 4 kanals AD-konverter] fra ArduinoTech&amp;lt;/ref&amp;gt;, der er købt som modul.&lt;br /&gt;
&lt;br /&gt;
For at kunne anvende modulet i koden skal der kommunikeres med modulet på en måde, som er angivet i beskrivelsen af modulet - det er dog ikke nødvendigt at sætte sig ind i den grundlæggende kommunikation, hvis man blot ønsker at få værdier ind i sin software. Som en dokumentation for hvordan man anvender biblioteket kan man skrive følgende:&lt;br /&gt;
&lt;br /&gt;
====Eksempel på dokumentation====&lt;br /&gt;
Til at hente værdierne fra den 4 kanals AD-konverter anvendes et bibliotek fundet på GitHub (Singh, 2018) som kan indlæse de analoge spændinger.&lt;br /&gt;
Til at sætte AD-konverteren rigtigt op, til at kunne læse 4 spændinger, så anvendes eksemplet ”ADS1115_SingleEnded.ino” og i setup skrives følgende kode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
    ads.getAddr_ADS1115(ADS1115_DEFAULT_ADDRESS);   // 0x48, 1001 000 (ADDR = GND)&lt;br /&gt;
    ads.setGain(GAIN_TWO);          // 2x gain   +/- 2.048V  1 bit = 0.0625mV (default)&lt;br /&gt;
    ads.setMode(MODE_CONTIN);       // Continuous conversion mode&lt;br /&gt;
    ads.setRate(RATE_128);          // 128SPS (default)&lt;br /&gt;
    ads.setOSMode(OSMODE_SINGLE);   // Set to start a single-conversion&lt;br /&gt;
    ads.begin();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
I [[loop()]] testes i første omgang, om det kan lade sig gøre at læse de 4 kanaler. Dette gøres ved at afvikle følgende testkode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
    address = ads.ads_i2cAddress;&lt;br /&gt;
    Wire.beginTransmission(address);&lt;br /&gt;
    error = Wire.endTransmission();&lt;br /&gt;
    if (error == 0)&lt;br /&gt;
    {&lt;br /&gt;
        int16_t adc0, adc1, adc2, adc3;&lt;br /&gt;
&lt;br /&gt;
        adc0 = ads.Measure_SingleEnded(0);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 1: &amp;quot;);&lt;br /&gt;
        Serial.println(adc0);&lt;br /&gt;
        adc1 = ads.Measure_SingleEnded(1);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 2: &amp;quot;);&lt;br /&gt;
        Serial.println(adc1);&lt;br /&gt;
        adc2 = ads.Measure_SingleEnded(2);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 3: &amp;quot;);&lt;br /&gt;
        Serial.println(adc2);&lt;br /&gt;
        adc3 = ads.Measure_SingleEnded(3);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 4: &amp;quot;);&lt;br /&gt;
        Serial.println(adc3);&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Denne test giver det ønskede resultat.&lt;br /&gt;
&lt;br /&gt;
Ud fra denne beskrivelse viser man, at man tager andres kode, og anvender ind i sit eget projekt, og man angiver præcist i sin beskrivelse hvad man har taget fra andres kode.&lt;br /&gt;
&lt;br /&gt;
I kildelisten vil kilden optræde på følgende måde:&lt;br /&gt;
&lt;br /&gt;
Singh, Y., 2018. Arduino Library ADS1115 16 bit 4 channel ADC. [Online] &amp;lt;br /&amp;gt;&lt;br /&gt;
Available at: https://github.com/ncdcommunity/Arduino_Library_ADS1115_16Bit_4Channel_ADC&amp;lt;br /&amp;gt;&lt;br /&gt;
[Senest hentet eller vist den 15 marts 2024].&lt;br /&gt;
&lt;br /&gt;
===ChatGPT som kilde til kode===&lt;br /&gt;
Det følgende er skrevet med udgangspunkt i det der er beskrevet på viden.ai&amp;lt;ref&amp;gt;[https://viden.ai/korrekt-kildehenvisning-af-chatgpt/ Korrekt kildehenvisning af ChatGPT]&amp;lt;/ref&amp;gt;. hvor der angives hvordan man kildehenviser, men også lidt om hvordan man håndterer det i tekst - i korte træk, lav et metodeafsnit, beskriv hvad man gør og vær meget redelig, ved at man angiver hvad man har fået af ChatGPT ved at lægge det ved som et bilag.&lt;br /&gt;
&lt;br /&gt;
Hvis man forstår at prompte fornuftigt, så er ChatGPT faktisk ret god til at foreslå kode, der kan anvendes, men ligesom det er plagiat hvis man kopierer fra nettet, så er det plagiat, hvis man lader ChatGPT skrive store dele af ens program for sig.&lt;br /&gt;
&lt;br /&gt;
Som det er formuleret i vejledningen til både programmering C og B, så kan man anvende ChatGPT til hjælp i fejlfinding af kode. For at kunne kildehenvise korrekt til hjælp med fejlfinding, så skal man angive hvad man har promptet til ChatGPT og hvad den har svaret - det kan placeres i bilag.&lt;br /&gt;
&lt;br /&gt;
En anden ting, som også er OK at få hjælp med er, at komme i gang med programmet - det er denne problematik der her gives et eksempel på. I eksemplet beskrives hvad man skal skrive i sin dokumentation, når man har anvendt denne hjælp, og der er forslag til hvordan man kommer videre i projektet.&lt;br /&gt;
&lt;br /&gt;
Konkret er det starten på udviklingen af et lille spil med bolde i et vindue, udviklet i Processing, der tages udgangspunkt i.&lt;br /&gt;
&lt;br /&gt;
====Metodeafsnit med omtale af ChatGPT====&lt;br /&gt;
Når man anvender CharGPT, så skal man dokumentere hvordan man har gjort det, og hvilke overvejelser der ligger bag det. Det betegnes i rapportskrivning som et metodeafsnit. Det kunne i dette eksempel lyde:&lt;br /&gt;
&lt;br /&gt;
For at få en fornuftig start på programkoden er der brugt ChatGPT til at få rammerne på koden etableret, og til at få et system, så der kan optræde flere bolde i programvinduet. Det er ChatGPT 3.5 (OpenAI, 2023)&amp;lt;ref&amp;gt;[https://chat.openai.com/chat Indgangen til ChatGPT 3.5]&amp;lt;/ref&amp;gt; der er anvendt til denne hjælp. Til programstarten blev der promptet efter at få et programvindue på 800x600 hvor en bold bevæger sig rundt. Den foreslåede kode blev kopieret ind i processings IDE (Processing, 2024)&amp;lt;ref&amp;gt;[https://processing.org Hovedsiden for Processing]&amp;lt;/ref&amp;gt; og testet – den opførte sig som forventet.&lt;br /&gt;
&lt;br /&gt;
Derefter blev der promptet efter at få den bold der bevægede sig til at dele sig op i to, når man klikker på den med musen. Dette resulterede i en væsentligt anderledes kode, som igen blev kopieret ind i processing og testet, og igen med et acceptabelt resultat. Dialogen med ChatGPT (OpenAI, 2023) og herunder de to koder, kan ses i bilag 1.&lt;br /&gt;
&lt;br /&gt;
Herefter er resten af koden udviklet på traditionel vis, hvor første trin var at dokumentere princippet i den foreslåede kode, specielt den Ball klasse der blev introduceret for at kunne arbejde med flere bolde i vinduet.&lt;br /&gt;
&lt;br /&gt;
Det nævnte bilag 1 [[media:ChatGPT-dialog-1.pdf|kan ses i denne PDF]].&lt;br /&gt;
&lt;br /&gt;
Når man opretter kilden i Word, så er det lidt forskelligt hvilke felter der er synlige, alt efter hvilken standard man har aktiv - men ved Harvard standarden kan indtastningerne se således ud:&lt;br /&gt;
&lt;br /&gt;
[[fil:citat-ChatGPT.png|Indtastningerne ved kildehenvisning til ChatGPT|600px]]&amp;lt;br /&amp;gt;&#039;&#039;Indtastningerne ved kildehenvisning til ChatGPT&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Mere om teknikken i at anvende kildelister kan ses på [https://holstebro-htx.dk/index.php/Word_Kildeliste Holstebro HTX Wiki - Kildelister].&lt;br /&gt;
&lt;br /&gt;
====Dokumentation af koden udviklet af ChatGPT====&lt;br /&gt;
Da der skulle kunne dannes nye bolde så oprettes der en klasse, som ChatGPT skriver det i dialogen i Bilag 1:&lt;br /&gt;
&lt;br /&gt;
: &#039;&#039;&amp;quot;Dette kodeeksempel opretter en klasse kaldet Ball, som repræsenterer boldobjekterne. Når musen klikkes, kontrolleres det, om musens position er inden for en bold. Hvis det er tilfældet, oprettes to nye boldobjekter, der bevæger sig i forskellige retninger, og den originale bold fjernes fra arrayet.&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Ved at teste koden kan man se at det ikke er det helt rigtige den formulerer - der oprettes godt nok to nye bold-objekter, men det er ikke den oprindelige bold der fjernes, det er den ene af de ny-oprettede bolde. Det kan ses ved at de to bolde kommer i samme position, og den ene fortsætter i samme retning (den oprindelige), mens den ny-oprettede går i en tilfældig retning. Dette rettes til senere i dokumentationen under &amp;quot;oprettelse af ny bold&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
For at have en god struktur i koden, så placeres klassen Ball i en fil for sig kaldet Ball. Denne fil starter med at definere koden som en klasse med linjen:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
class Ball {&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dernæst defineres klassens egenskaber, der er boldens position og hastighed samt en fast diameter. Ud over det er der en x- og y-retning defineret. Den anvendes til at sige om bolden bevæger sig i en positiv eller negativ retning, så de skifter mellem +1 og -1, når kanterne rammes.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  float x, y;&lt;br /&gt;
  float xspeed, yspeed;&lt;br /&gt;
  int diameter = 30;&lt;br /&gt;
  int xdirection = 1;&lt;br /&gt;
  int ydirection = 1;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der defineres to forskellige constructors til bolden. Den første anvendes til at danne den første bold med, hvor position og hastighed sættes tilfældigt.&lt;br /&gt;
&lt;br /&gt;
Her forudses et problem at der kan komme et randfænomen, hvis bolden dannes, så den ligger med noget uden for skærmen. Da det er tilfældigt; så er det sjældent problemet opstår. For at fremprovokere det oftere er det testet med en diameter på 200, hvor det kunne ses at bolden bliver &amp;quot;hængende&amp;quot; i kanten.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  Ball() {&lt;br /&gt;
    x = random(width);&lt;br /&gt;
    y = random(height);&lt;br /&gt;
    xspeed = random(0.5, 2);&lt;br /&gt;
    yspeed = random(0.5, 2);&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Dette rettes ved at omskrive den foreslåede constructor til følgende kode, hvor bolden placeres mindst en halv diameter fra kanten:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  Ball() {&lt;br /&gt;
    x = random(diameter / 2, width - diameter / 2);&lt;br /&gt;
    y = random(diameter / 2, height - diameter / 2);&lt;br /&gt;
    xspeed = random(0.5, 2);&lt;br /&gt;
    yspeed = random(0.5, 2);&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Den anden constructor tager fire parametre, der er positionen og hastigheden. Denne constructor anvendes, når der skal dannes nye bolde, hvor koden netop skal starte den nye bold i den oprindelige bolds position, og med en ny retning.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  Ball(float x, float y, float xspeed, float yspeed) {&lt;br /&gt;
    this.x = x;&lt;br /&gt;
    this.y = y;&lt;br /&gt;
    this.xspeed = xspeed;&lt;br /&gt;
    this.yspeed = yspeed;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ud over disse standard ting til oprettelsen af objekter, så er der 3 metoder i klassen. Den første er en move() metode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  void move() {&lt;br /&gt;
    x = x + (xspeed * xdirection);&lt;br /&gt;
    y = y + (yspeed * ydirection);&lt;br /&gt;
&lt;br /&gt;
    if ((x + diameter/2 &amp;gt;= width) || (x - diameter/2 &amp;lt;= 0)) {&lt;br /&gt;
      xdirection *= -1;&lt;br /&gt;
    }&lt;br /&gt;
    if ((y + diameter/2 &amp;gt;= height) || (y - diameter/2 &amp;lt;= 0)) {&lt;br /&gt;
      ydirection *= -1;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Måden metoden virker på er at den lægger hastigheden til boldens position (både x og y), og hvis boldens position (både i x og y) er kommet uden for rammen, så ændres retningen for enten x eller y.&lt;br /&gt;
&lt;br /&gt;
For at kunne vise bolden er der en display() metode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  void display() {&lt;br /&gt;
    ellipse(x, y, diameter, diameter);&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Den sidste metode hedder contains(), og den tager en position som parameter til metoden. Der undersøges så om den position ligger inden for bolden ved at se om afstanden mellem boldens center og den testede position er mindre end den halve diameter. Hvis den er inden for bolden, så returneres true, ellers returneres false:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  boolean contains(float x, float y) {&lt;br /&gt;
    float d = dist(x, y, this.x, this.y);&lt;br /&gt;
    if (d &amp;lt; diameter/2) {&lt;br /&gt;
      return true;&lt;br /&gt;
    } else {&lt;br /&gt;
      return false;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Oprettelse af ny bold====&lt;br /&gt;
I den oprindelige kode undersøges om der er klikket på en bold, ved at alle bolde løbes igennem i mousePressed() funktionen, og med metoden contains undersøges om der er klikket på en bold. Denne måde at undersøge alle bolde på beholdes.&lt;br /&gt;
&lt;br /&gt;
Som omtalt er det ikke den smarteste måde til at dele bolden op i to, der anvendes. Som det ses i koden herunder, så appendes der to nye bolde på med den oprindelige bolds x- og y-position på samt tilfældige x- og y-hastigheder. Disse to bolde lægges i slutningen af arrayet. Derefter anvendes shorten&amp;lt;ref&amp;gt;[https://processing.org/reference/shorten_.html Processings shorten metode til arrays]&amp;lt;/ref&amp;gt; til at fjerne et element, men da det element der fjernes er det sidste element i arrayet, så fjernes der bare den sidst oprettede bold.&lt;br /&gt;
&lt;br /&gt;
Hvis man var tilfreds med den opførsel, så kunne man blot fjerne kodelinjen med den anden append og kodelinjen med shorten. Så ville man have samme funktion.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
    if (balls[i].contains(mouseX, mouseY)) {&lt;br /&gt;
      balls = (Ball[]) append(balls, new Ball(balls[i].x, balls[i].y, random(-5, 5), random(-5, 5)));&lt;br /&gt;
      balls = (Ball[]) append(balls, new Ball(balls[i].x, balls[i].y, random(-5, 5), random(-5, 5)));&lt;br /&gt;
      balls = (Ball[]) shorten(balls);&lt;br /&gt;
      break;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Den nye bold der oprettes får bare en tilfældig retning, og den oprindelige bold fortsætter bare i den retning den var på vej i. Det er ikke den opførsel der ønskes i spillet. Der ønskes i stedet at det ser ud som om bolden &amp;quot;splittes op&amp;quot; i 2 bolde, og den opførsel laves ved at lade den oprindelige bold ændre 30 grader til den ene side, og den nye bold får 30 grader til den anden side.&lt;br /&gt;
&lt;br /&gt;
For at gøre dette, så oprettes der en metode multiply() i klassen Ball. Denne metode returnerer en ny bold af typen Ball, så nu kan koden i museklikket skrives som følger:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
    if (balls[i].contains(mouseX, mouseY)) {&lt;br /&gt;
      balls = (Ball[]) append(balls, balls[i].multiply());&lt;br /&gt;
      break;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Som det kan ses, så appendes der en ny bold ind i balls-arrayet, ud fra metoden multiply().&lt;br /&gt;
&lt;br /&gt;
Metoden multiply() oprettes inde i klassen med følgende kode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  Ball multiply() {&lt;br /&gt;
    xspeed *= xdirection;&lt;br /&gt;
    yspeed *= ydirection;&lt;br /&gt;
    xdirection = 1;&lt;br /&gt;
    ydirection = 1;&lt;br /&gt;
    float speed = dist(0, 0, xspeed, yspeed);&lt;br /&gt;
    float angle = acos(xspeed / speed);&lt;br /&gt;
    if (yspeed &amp;lt; 0) angle = 0.0 - angle;&lt;br /&gt;
    speed *= 1.5;&lt;br /&gt;
    xspeed = speed * cos(angle + PI / 6);&lt;br /&gt;
    yspeed = speed * sin(angle + PI / 6);&lt;br /&gt;
    Ball b = new Ball(x, y, speed * cos(angle - PI / 6), speed * sin(angle - PI / 6));&lt;br /&gt;
    return b;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Først regnes retningen over i xspeed og yspeed, så de kan være både positive og negative. På den måde indeholder de to variabler retningen.&lt;br /&gt;
&lt;br /&gt;
Dernæst omregnes x- og y-hastigheden til en samlet hastighed speed og en vinkel angle, som kan være mellem +PI og -PI (+/- 180 grader).&lt;br /&gt;
&lt;br /&gt;
Begge bolde skal bevæge sig hurtigere efter de er delt, så spillet gradvist bliver sværere, derfor ganges hastigheden med 1,5.&lt;br /&gt;
&lt;br /&gt;
Den oprindelige bold får nu en ny retning, ved at udregne x- og y-hastigheden ud fra den nye hastighed og vinklen plus 30 grader.&lt;br /&gt;
&lt;br /&gt;
Til sidst oprettes en ny bold med samme position som den oprindelige og en x- og y-hastighed udregnet fra den oprindelige bolds hastighed og vinklen minus 30 grader. Denne bold returneres fra metoden.&lt;br /&gt;
&lt;br /&gt;
==Refleksioner over anvendelsen==&lt;br /&gt;
Der er selvfølgelig stadig lang vej til man har et færdigt spil, men ideen var også at tage fat i, hvordan man anvender ChatGPT på en ordentlig og redelig måde i et programmeringsprojekt. Dette kan selvfølgelig altid gradbøjes, men hvis man håndterer anvendelsen som vist i eksemplet, så vil man ikke gøre noget der kommer i nærheden af plagiat.&lt;br /&gt;
&lt;br /&gt;
==Referencer== &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt; &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Programmering}}&lt;br /&gt;
&lt;br /&gt;
[[Kategori:Programmering teknik]]&lt;/div&gt;</summary>
		<author><name>Bar</name></author>
	</entry>
	<entry>
		<id>https://www.htxarduino.dk/index.php?title=Programmering_med_ChatGPT&amp;diff=5405</id>
		<title>Programmering med ChatGPT</title>
		<link rel="alternate" type="text/html" href="https://www.htxarduino.dk/index.php?title=Programmering_med_ChatGPT&amp;diff=5405"/>
		<updated>2024-03-18T20:27:48Z</updated>

		<summary type="html">&lt;p&gt;Bar: /* Metodeafsnit med omtale af ChatGPT */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Det er ikke så svært at få ChatGPT&amp;lt;ref&amp;gt;[https://chat.openai.com/auth/login ChatGPT Login] - Indgangen til ChatGPT&amp;lt;/ref&amp;gt; til at lave kode, der skal man blot beskrive hvad man gerne vil have programmet til at gøre, og så kopiere den kode, der kommer ud af det - det giver tit ret gode resultater.&lt;br /&gt;
&lt;br /&gt;
Problemet med at anvende ChatGPT i forbindelse med skoleprojekter er, at man skal have forståelsen med i det, og at man ikke kan blive anklaget for plagiat.&lt;br /&gt;
&lt;br /&gt;
==Hvad må man ikke i en skoleprojekt==&lt;br /&gt;
*Man må ikke kopiere kode, som man ikke selv har skrevet, til et programmeringsprodukt uden at man angiver en kilde. Det er uanset hvor koden stammer fra, også selvom man har brugt ChatGPT til at &amp;quot;udvikle&amp;quot; koden.&lt;br /&gt;
*Man må ikke aflevere et produkt hvor de primære dele af koden er kopieret, heller ikke selvom man kildehenviser.&lt;br /&gt;
*Man må ikke få ChatGPT til at dokumentere sin kode, ved at man kopierer ChatGPT&#039;s beskrivelse ind i sin dokumentation af koden.&lt;br /&gt;
&lt;br /&gt;
De beskrevne eksempler er at betragte som plagiat, og vil blive håndteret efter skolens ordensregler, hvilket i værste fald kan ende med at et fag annulleres eller man bliver bortvist fra uddannelsen.&lt;br /&gt;
==Hvad er tilladt med ChatGPT==&lt;br /&gt;
På samme måde som man må anvende kilder fra internettet, så må man i programmerings-faget i gymnasiet anvende ChatGPT i udviklingen af kode til et programmeringsprodukt. Dette er blevet tilladt via en revidering af vejledningen til faget&amp;lt;ref&amp;gt;[https://www.uvm.dk/-/media/filer/uvm/udd/gym/pdf23/aug/vejledninger/valgfag/230807-programmering-c--valgfag.pdf Vejledning] til Valgfaget Programmering C&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
I vejledningen står der som følger:&lt;br /&gt;
&lt;br /&gt;
: &#039;&#039;&amp;quot;brug af internettet er tilladt som fagligt hjælpemiddel ved de mundtlige prøver, inkluderer de tilladte hjælpemidler anvendelsen af chatbots og lignende på en måde, som afspejler, hvordan man arbejder i den daglige undervisning. Dette kunne fx være brug af ChatGPT til at debugge kode.&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Det skal altså afspejle den normale brug, som man også har ved at bruge internettet. Som angivet under hvad man ikke må, så er den normale brug, at man anvender information til at lære at programmere, men at man ikke tager så meget af sit produkt fra nettet, så man ikke har en forståelse af hvordan produktet er sammensat.&lt;br /&gt;
&lt;br /&gt;
Videre i vejledningen står der:&lt;br /&gt;
&lt;br /&gt;
: &#039;&#039;&amp;quot;I forhold til denne type hjælpemidler er det vigtigt at være opmærksom på, at den tilladte anvendelse er betinget af, at hjælpemidlerne kun benyttes i et omfang, hvor prøvebesvarelsen er selvstændig og udelukkende elevens egen.&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Igen understreges at det der afleveres skal være elevens selvstændigt udviklede produkt og dokumentation, hvor man på normal vis anvender internettet som et værktøj til at bibringe forståelse.&lt;br /&gt;
&lt;br /&gt;
==Problemet med ChatGPT==&lt;br /&gt;
Ligesom man ikke kan kilde-henvise til &amp;quot;google&amp;quot;, for at angive at man har fundet informationer på nettet, så kan man heller ikke kildehenvise til ChatGPT direkte som en kilde.&lt;br /&gt;
&lt;br /&gt;
Når man finder informationer med google&#039;, så skal man angive hvor på nettet man har fundet dem med så præcis en kildehenvisning, at man kan se den information der er blevet anvendt.&lt;br /&gt;
&lt;br /&gt;
Denne type henvisning kan man ikke lave i forhold til ChatGPT, da sprogmodellen der ligger bag ChatGPT konstant udvikler sig, samt at de svar sprogmodellen giver har et randomiseret element indbygget, som er med til at give bedre svar&amp;lt;ref&amp;gt;[https://www.it-vest.dk/arrangementer/sig-webinar-14-marts-2024-kunstig-intelligens-og-chatgpt-hvordan-virker-det-og-skal-vi-bare-opgive-undervisning-og-eksamen Webinar om kunstig intelligens]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Her er man altså nødt til at tage andre metoder i brug, for at kunne dokumentere at man har udviklet sit produkt ordentligt og redeligt.&lt;br /&gt;
&lt;br /&gt;
==Kildehenvisninger i dokumentation==&lt;br /&gt;
Der kan være forskellige standarder for hvordan man kildehenviser i forskellige uddannelser, dette er skrevet med udgangspunkt i at man anvender Word bibliografi-værktøj og her vist med en Harvard-lignende standard&amp;lt;ref&amp;gt;[https://holstebro-htx.dk/index.php/Word_Kildeliste Kildelister] anvendt i Microsoft Word&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Normal Internet-kilde til kode===&lt;br /&gt;
I dette eksempel er der angivet hvordan man ville dokumentere at man har anvendt kode fra et bibliotek til noget hardware på en [[Arduino]]. I det tænkte eksempel er det en 4 kanals AD-konverter&amp;lt;ref&amp;gt;[https://arduinotech.dk/shop/ads1115-module-4-channel-16-bit-i2c-adc-with-pro-gain-amplifier 4 kanals AD-konverter] fra ArduinoTech&amp;lt;/ref&amp;gt;, der er købt som modul.&lt;br /&gt;
&lt;br /&gt;
For at kunne anvende modulet i koden skal der kommunikeres med modulet på en måde, som er angivet i beskrivelsen af modulet - det er dog ikke nødvendigt at sætte sig ind i den grundlæggende kommunikation, hvis man blot ønsker at få værdier ind i sin software. Som en dokumentation for hvordan man anvender biblioteket kan man skrive følgende:&lt;br /&gt;
&lt;br /&gt;
====Eksempel på dokumentation====&lt;br /&gt;
Til at hente værdierne fra den 4 kanals AD-konverter anvendes et bibliotek fundet på GitHub (Singh, 2018) som kan indlæse de analoge spændinger.&lt;br /&gt;
Til at sætte AD-konverteren rigtigt op, til at kunne læse 4 spændinger, så anvendes eksemplet ”ADS1115_SingleEnded.ino” og i setup skrives følgende kode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
    ads.getAddr_ADS1115(ADS1115_DEFAULT_ADDRESS);   // 0x48, 1001 000 (ADDR = GND)&lt;br /&gt;
    ads.setGain(GAIN_TWO);          // 2x gain   +/- 2.048V  1 bit = 0.0625mV (default)&lt;br /&gt;
    ads.setMode(MODE_CONTIN);       // Continuous conversion mode&lt;br /&gt;
    ads.setRate(RATE_128);          // 128SPS (default)&lt;br /&gt;
    ads.setOSMode(OSMODE_SINGLE);   // Set to start a single-conversion&lt;br /&gt;
    ads.begin();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
I [[loop()]] testes i første omgang, om det kan lade sig gøre at læse de 4 kanaler. Dette gøres ved at afvikle følgende testkode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
    address = ads.ads_i2cAddress;&lt;br /&gt;
    Wire.beginTransmission(address);&lt;br /&gt;
    error = Wire.endTransmission();&lt;br /&gt;
    if (error == 0)&lt;br /&gt;
    {&lt;br /&gt;
        int16_t adc0, adc1, adc2, adc3;&lt;br /&gt;
&lt;br /&gt;
        adc0 = ads.Measure_SingleEnded(0);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 1: &amp;quot;);&lt;br /&gt;
        Serial.println(adc0);&lt;br /&gt;
        adc1 = ads.Measure_SingleEnded(1);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 2: &amp;quot;);&lt;br /&gt;
        Serial.println(adc1);&lt;br /&gt;
        adc2 = ads.Measure_SingleEnded(2);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 3: &amp;quot;);&lt;br /&gt;
        Serial.println(adc2);&lt;br /&gt;
        adc3 = ads.Measure_SingleEnded(3);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 4: &amp;quot;);&lt;br /&gt;
        Serial.println(adc3);&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Denne test giver det ønskede resultat.&lt;br /&gt;
&lt;br /&gt;
Ud fra denne beskrivelse viser man, at man tager andres kode, og anvender ind i sit eget projekt, og man angiver præcist i sin beskrivelse hvad man har taget fra andres kode.&lt;br /&gt;
&lt;br /&gt;
I kildelisten vil kilden optræde på følgende måde:&lt;br /&gt;
&lt;br /&gt;
Singh, Y., 2018. Arduino Library ADS1115 16 bit 4 channel ADC. [Online] &amp;lt;br /&amp;gt;&lt;br /&gt;
Available at: https://github.com/ncdcommunity/Arduino_Library_ADS1115_16Bit_4Channel_ADC&amp;lt;br /&amp;gt;&lt;br /&gt;
[Senest hentet eller vist den 15 marts 2024].&lt;br /&gt;
&lt;br /&gt;
===ChatGPT som kilde til kode===&lt;br /&gt;
Det følgende er skrevet med udgangspunkt i det der er beskrevet på viden.ai&amp;lt;ref&amp;gt;[https://viden.ai/korrekt-kildehenvisning-af-chatgpt/ Korrekt kildehenvisning af ChatGPT]&amp;lt;/ref&amp;gt;. hvor der angives hvordan man kildehenviser, men også lidt om hvordan man håndterer det i tekst - i korte træk, lav et metodeafsnit, beskriv hvad man gør og vær meget redelig, ved at man angiver hvad man har fået af ChatGPT ved at lægge det ved som et bilag.&lt;br /&gt;
&lt;br /&gt;
Hvis man forstår at prompte fornuftigt, så er ChatGPT faktisk ret god til at foreslå kode, der kan anvendes, men ligesom det er plagiat hvis man kopierer fra nettet, så er det plagiat, hvis man lader ChatGPT skrive store dele af ens program for sig.&lt;br /&gt;
&lt;br /&gt;
Som det er formuleret i vejledningen til både programmering C og B, så kan man anvende ChatGPT til hjælp i fejlfinding af kode. For at kunne kildehenvise korrekt til hjælp med fejlfinding, så skal man angive hvad man har promptet til ChatGPT og hvad den har svaret - det kan placeres i bilag.&lt;br /&gt;
&lt;br /&gt;
En anden ting, som også er OK at få hjælp med er, at komme i gang med programmet - det er denne problematik der her gives et eksempel på. I eksemplet beskrives hvad man skal skrive i sin dokumentation, når man har anvendt denne hjælp, og der er forslag til hvordan man kommer videre i projektet.&lt;br /&gt;
&lt;br /&gt;
Konkret er det starten på udviklingen af et lille spil med bolde i et vindue, udviklet i Processing, der tages udgangspunkt i.&lt;br /&gt;
&lt;br /&gt;
====Metodeafsnit med omtale af ChatGPT====&lt;br /&gt;
Når man anvender CharGPT, så skal man dokumentere hvordan man har gjort det, og hvilke overvejelser der ligger bag det. Det betegnes i rapportskrivning som et metodeafsnit. Det kunne i dette eksempel lyde:&lt;br /&gt;
&lt;br /&gt;
For at få en fornuftig start på programkoden er der brugt ChatGPT til at få rammerne på koden etableret, og til at få et system, så der kan optræde flere bolde i programvinduet. Det er ChatGPT 3.5 (OpenAI, 2023)&amp;lt;ref&amp;gt;[https://chat.openai.com/chat Indgangen til ChatGPT 3.5]&amp;lt;/ref&amp;gt; der er anvendt til denne hjælp. Til programstarten blev der promptet efter at få et programvindue på 800x600 hvor en bold bevæger sig rundt. Den foreslåede kode blev kopieret ind i processings IDE (Processing, 2024)&amp;lt;ref&amp;gt;[https://processing.org Hovedsiden for Processing]&amp;lt;/ref&amp;gt; og testet – den opførte sig som forventet.&lt;br /&gt;
&lt;br /&gt;
Derefter blev der promptet efter at få den bold der bevægede sig til at dele sig op i to, når man klikker på den med musen. Dette resulterede i en væsentligt anderledes kode, som igen blev kopieret ind i processing og testet, og igen med et acceptabelt resultat. Dialogen med ChatGPT (OpenAI, 2023) og herunder de to koder, kan ses i bilag 1.&lt;br /&gt;
&lt;br /&gt;
Herefter er resten af koden udviklet på traditionel vis, hvor første trin var at dokumentere princippet i den foreslåede kode, specielt den Ball klasse der blev introduceret for at kunne arbejde med flere bolde i vinduet.&lt;br /&gt;
&lt;br /&gt;
Det nævnte bilag 1 [[media:ChatGPT-dialog-1.pdf|kan ses i denne PDF]].&lt;br /&gt;
&lt;br /&gt;
Når man opretter kilden i Word, så er det lidt forskelligt hvilke felter der er synlige, alt efter hvilken standard man har aktiv - men ved Harvard standarden kan indtastningerne se således ud:&lt;br /&gt;
&lt;br /&gt;
[[fil:citat-ChatGPT.png|Indtastningerne ved kildehenvisning til ChatGPT|600px]]&amp;lt;br /&amp;gt;&#039;&#039;Indtastningerne ved kildehenvisning til ChatGPT&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Mere om teknikken i at anvende kildelister kan ses på [https://holstebro-htx.dk/index.php/Word_Kildeliste Holstebro HTX Wiki - Kildelister].&lt;br /&gt;
&lt;br /&gt;
====Dokumentation af koden udviklet af ChatGPT====&lt;br /&gt;
Da der skulle kunne dannes nye bolde så oprettes der en klasse, som ChatGPT skriver det i dialogen i Bilag 1:&lt;br /&gt;
&lt;br /&gt;
: &#039;&#039;&amp;quot;Dette kodeeksempel opretter en klasse kaldet Ball, som repræsenterer boldobjekterne. Når musen klikkes, kontrolleres det, om musens position er inden for en bold. Hvis det er tilfældet, oprettes to nye boldobjekter, der bevæger sig i forskellige retninger, og den originale bold fjernes fra arrayet.&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Ved at teste koden kan man se at det ikke er det helt rigtige den formulerer - der oprettes godt nok to nye bold-objekter, men det er ikke den oprindelige bold der fjernes, det er den ene af de ny-oprettede bolde. Det kan ses ved at de to bolde kommer i samme position, og den ene fortsætter i samme retning (den oprindelige), mens den ny-oprettede går i en tilfældig retning. Dette rettes til senere i dokumentationen under &amp;quot;oprettelse af ny bold&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
For at have en god struktur i koden, så placeres klassen Ball i en fil for sig kaldet Ball. Denne fil starter med at definere koden som en klasse med linjen:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
class Ball {&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dernæst defineres klassens egenskaber, der er boldens position og hastighed samt en fast diameter. Ud over det er der en x- og y-retning defineret. Den anvendes til at sige om bolden bevæger sig i en positiv eller negativ retning, så de skifter mellem +1 og -1, når kanterne rammes.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  float x, y;&lt;br /&gt;
  float xspeed, yspeed;&lt;br /&gt;
  int diameter = 30;&lt;br /&gt;
  int xdirection = 1;&lt;br /&gt;
  int ydirection = 1;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der defineres to forskellige constructors til bolden. Den første anvendes til at danne den første bold med, hvor position og hastighed sættes tilfældigt.&lt;br /&gt;
&lt;br /&gt;
Her forudses et problem at der kan komme et randfænomen, hvis bolden dannes, så den ligger med noget uden for skærmen. Da det er tilfældigt; så er det sjældent problemet opstår. For at fremprovokere det oftere er det testet med en diameter på 200, hvor det kunne ses at bolden bliver &amp;quot;hængende&amp;quot; i kanten.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  Ball() {&lt;br /&gt;
    x = random(width);&lt;br /&gt;
    y = random(height);&lt;br /&gt;
    xspeed = random(0.5, 2);&lt;br /&gt;
    yspeed = random(0.5, 2);&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Dette rettes ved at omskrive den foreslåede constructor til følgende kode, hvor bolden placeres mindst en halv diameter fra kanten:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  Ball() {&lt;br /&gt;
    x = random(diameter / 2, width - diameter / 2);&lt;br /&gt;
    y = random(diameter / 2, height - diameter / 2);&lt;br /&gt;
    xspeed = random(0.5, 2);&lt;br /&gt;
    yspeed = random(0.5, 2);&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Den anden constructor tager fire parametre, der er positionen og hastigheden. Denne constructor anvendes, når der skal dannes nye bolde, hvor koden netop skal starte den nye bold i den oprindelige bolds position, og med en ny retning.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  Ball(float x, float y, float xspeed, float yspeed) {&lt;br /&gt;
    this.x = x;&lt;br /&gt;
    this.y = y;&lt;br /&gt;
    this.xspeed = xspeed;&lt;br /&gt;
    this.yspeed = yspeed;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ud over disse standard ting til oprettelsen af objekter, så er der 3 metoder i klassen. Den første er en move() metode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  void move() {&lt;br /&gt;
    x = x + (xspeed * xdirection);&lt;br /&gt;
    y = y + (yspeed * ydirection);&lt;br /&gt;
&lt;br /&gt;
    if ((x + diameter/2 &amp;gt;= width) || (x - diameter/2 &amp;lt;= 0)) {&lt;br /&gt;
      xdirection *= -1;&lt;br /&gt;
    }&lt;br /&gt;
    if ((y + diameter/2 &amp;gt;= height) || (y - diameter/2 &amp;lt;= 0)) {&lt;br /&gt;
      ydirection *= -1;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Måden metoden virker på er at den lægger hastigheden til boldens position (både x og y), og hvis boldens position (både i x og y) er kommet uden for rammen, så ændres retningen for enten x eller y.&lt;br /&gt;
&lt;br /&gt;
For at kunne vise bolden er der en display() metode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  void display() {&lt;br /&gt;
    ellipse(x, y, diameter, diameter);&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Den sidste metode hedder contains(), og den tager en position som parameter til metoden. Der undersøges så om den position ligger inden for bolden ved at se om afstanden mellem boldens center og den testede position er mindre end den halve diameter. Hvis den er inden for bolden, så returneres true, ellers returneres false:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  boolean contains(float x, float y) {&lt;br /&gt;
    float d = dist(x, y, this.x, this.y);&lt;br /&gt;
    if (d &amp;lt; diameter/2) {&lt;br /&gt;
      return true;&lt;br /&gt;
    } else {&lt;br /&gt;
      return false;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Oprettelse af ny bold====&lt;br /&gt;
I den oprindelige kode undersøges om der er klikket på en bold, ved at alle bolde løbes igennem i mousePressed() funktionen, og med metoden contains undersøges om der er klikket på en bold. Denne måde at undersøge alle bolde på beholdes.&lt;br /&gt;
&lt;br /&gt;
Som omtalt er det ikke den smarteste måde til at dele bolden op i to, der anvendes. Som det ses i koden herunder, så appendes der to nye bolde på med den oprindelige bolds x- og y-position på samt tilfældige x- og y-hastigheder. Disse to bolde lægges i slutningen af arrayet. Derefter anvendes shorten&amp;lt;ref&amp;gt;[https://processing.org/reference/shorten_.html Processings shorten metode til arrays]&amp;lt;/ref&amp;gt; til at fjerne et element, men da det element der fjernes er det sidste element i arrayet, så fjernes der bare den sidst oprettede bold.&lt;br /&gt;
&lt;br /&gt;
Hvis man var tilfreds med den opførsel, så kunne man blot fjerne kodelinjen med den anden append og kodelinjen med shorten. Så ville man have samme funktion.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
    if (balls[i].contains(mouseX, mouseY)) {&lt;br /&gt;
      balls = (Ball[]) append(balls, new Ball(balls[i].x, balls[i].y, random(-5, 5), random(-5, 5)));&lt;br /&gt;
      balls = (Ball[]) append(balls, new Ball(balls[i].x, balls[i].y, random(-5, 5), random(-5, 5)));&lt;br /&gt;
      balls = (Ball[]) shorten(balls);&lt;br /&gt;
      break;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Den nye bold der oprettes får bare en tilfældig retning, og den oprindelige bold fortsætter bare i den retning den var på vej i. Det er ikke den opførsel der ønskes i spillet. Der ønskes i stedet at det ser ud som om bolden &amp;quot;splittes op&amp;quot; i 2 bolde, og den opførsel laves ved at lade den oprindelige bold ændre 30 grader til den ene side, og den nye bold får 30 grader til den anden side.&lt;br /&gt;
&lt;br /&gt;
For at gøre dette, så oprettes der en metode multiply() i klassen Ball. Denne metode returnerer en ny bold af typen Ball, så nu kan koden i museklikket skrives som følger:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
    if (balls[i].contains(mouseX, mouseY)) {&lt;br /&gt;
      balls = (Ball[]) append(balls, balls[i].multiply());&lt;br /&gt;
      break;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Som det kan ses, så appendes der en ny bold ind i balls-arrayet, ud fra metoden multiply().&lt;br /&gt;
&lt;br /&gt;
Metoden multiply() oprettes inde i klassen med følgende kode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  Ball multiply() {&lt;br /&gt;
    xspeed *= xdirection;&lt;br /&gt;
    yspeed *= ydirection;&lt;br /&gt;
    xdirection = 1;&lt;br /&gt;
    ydirection = 1;&lt;br /&gt;
    float speed = dist(0, 0, xspeed, yspeed);&lt;br /&gt;
    float angle = acos(xspeed / speed);&lt;br /&gt;
    if (yspeed &amp;lt; 0) angle = 0.0 - angle;&lt;br /&gt;
    speed *= 1.5;&lt;br /&gt;
    xspeed = speed * cos(angle + PI / 6);&lt;br /&gt;
    yspeed = speed * sin(angle + PI / 6);&lt;br /&gt;
    Ball b = new Ball(x, y, speed * cos(angle - PI / 6), speed * sin(angle - PI / 6));&lt;br /&gt;
    return b;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Først regnes retningen over i xspeed og yspeed, så de kan være både positive og negative. På den måde indeholder de to variabler retningen.&lt;br /&gt;
&lt;br /&gt;
Dernæst omregnes x- og y-hastigheden til en samlet hastighed speed og en vinkel angle, som kan være mellem +PI og -PI (+/- 180 grader).&lt;br /&gt;
&lt;br /&gt;
Begge bolde skal bevæge sig hurtigere efter de er delt, så spillet gradvist bliver sværere, derfor ganges hastigheden med 1,5.&lt;br /&gt;
&lt;br /&gt;
Den oprindelige bold får nu en ny retning, ved at udregne x- og y-hastigheden ud fra den nye hastighed og vinklen plus 30 grader.&lt;br /&gt;
&lt;br /&gt;
Til sidst oprettes en ny bold med samme position som den oprindelige og en x- og y-hastighed udregnet fra den oprindelige bolds hastighed og vinklen minus 30 grader. Denne bold returneres fra metoden.&lt;br /&gt;
&lt;br /&gt;
==Refleksioner over anvendelsen==&lt;br /&gt;
Der er selvfølgelig stadig lang vej til man har et færdigt spil, men ideen var også at tage fat i, hvordan man anvender ChatGPT på en ordentlig og redelig måde i et programmeringsprojekt. Dette kan selvfølgelig altid gradbøjes, men hvis man håndterer anvendelsen som vist i eksemplet, så vil man ikke gøre noget der kommer i nærheden af plagiat.&lt;br /&gt;
&lt;br /&gt;
==Referencer== &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt; &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Programmering}}&lt;br /&gt;
&lt;br /&gt;
[[Kategori:Programmering teknik]]&lt;/div&gt;</summary>
		<author><name>Bar</name></author>
	</entry>
	<entry>
		<id>https://www.htxarduino.dk/index.php?title=Programmering_med_ChatGPT&amp;diff=5404</id>
		<title>Programmering med ChatGPT</title>
		<link rel="alternate" type="text/html" href="https://www.htxarduino.dk/index.php?title=Programmering_med_ChatGPT&amp;diff=5404"/>
		<updated>2024-03-18T20:27:09Z</updated>

		<summary type="html">&lt;p&gt;Bar: /* Metodeafsnit med omtale af ChatGPT */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Det er ikke så svært at få ChatGPT&amp;lt;ref&amp;gt;[https://chat.openai.com/auth/login ChatGPT Login] - Indgangen til ChatGPT&amp;lt;/ref&amp;gt; til at lave kode, der skal man blot beskrive hvad man gerne vil have programmet til at gøre, og så kopiere den kode, der kommer ud af det - det giver tit ret gode resultater.&lt;br /&gt;
&lt;br /&gt;
Problemet med at anvende ChatGPT i forbindelse med skoleprojekter er, at man skal have forståelsen med i det, og at man ikke kan blive anklaget for plagiat.&lt;br /&gt;
&lt;br /&gt;
==Hvad må man ikke i en skoleprojekt==&lt;br /&gt;
*Man må ikke kopiere kode, som man ikke selv har skrevet, til et programmeringsprodukt uden at man angiver en kilde. Det er uanset hvor koden stammer fra, også selvom man har brugt ChatGPT til at &amp;quot;udvikle&amp;quot; koden.&lt;br /&gt;
*Man må ikke aflevere et produkt hvor de primære dele af koden er kopieret, heller ikke selvom man kildehenviser.&lt;br /&gt;
*Man må ikke få ChatGPT til at dokumentere sin kode, ved at man kopierer ChatGPT&#039;s beskrivelse ind i sin dokumentation af koden.&lt;br /&gt;
&lt;br /&gt;
De beskrevne eksempler er at betragte som plagiat, og vil blive håndteret efter skolens ordensregler, hvilket i værste fald kan ende med at et fag annulleres eller man bliver bortvist fra uddannelsen.&lt;br /&gt;
==Hvad er tilladt med ChatGPT==&lt;br /&gt;
På samme måde som man må anvende kilder fra internettet, så må man i programmerings-faget i gymnasiet anvende ChatGPT i udviklingen af kode til et programmeringsprodukt. Dette er blevet tilladt via en revidering af vejledningen til faget&amp;lt;ref&amp;gt;[https://www.uvm.dk/-/media/filer/uvm/udd/gym/pdf23/aug/vejledninger/valgfag/230807-programmering-c--valgfag.pdf Vejledning] til Valgfaget Programmering C&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
I vejledningen står der som følger:&lt;br /&gt;
&lt;br /&gt;
: &#039;&#039;&amp;quot;brug af internettet er tilladt som fagligt hjælpemiddel ved de mundtlige prøver, inkluderer de tilladte hjælpemidler anvendelsen af chatbots og lignende på en måde, som afspejler, hvordan man arbejder i den daglige undervisning. Dette kunne fx være brug af ChatGPT til at debugge kode.&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Det skal altså afspejle den normale brug, som man også har ved at bruge internettet. Som angivet under hvad man ikke må, så er den normale brug, at man anvender information til at lære at programmere, men at man ikke tager så meget af sit produkt fra nettet, så man ikke har en forståelse af hvordan produktet er sammensat.&lt;br /&gt;
&lt;br /&gt;
Videre i vejledningen står der:&lt;br /&gt;
&lt;br /&gt;
: &#039;&#039;&amp;quot;I forhold til denne type hjælpemidler er det vigtigt at være opmærksom på, at den tilladte anvendelse er betinget af, at hjælpemidlerne kun benyttes i et omfang, hvor prøvebesvarelsen er selvstændig og udelukkende elevens egen.&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Igen understreges at det der afleveres skal være elevens selvstændigt udviklede produkt og dokumentation, hvor man på normal vis anvender internettet som et værktøj til at bibringe forståelse.&lt;br /&gt;
&lt;br /&gt;
==Problemet med ChatGPT==&lt;br /&gt;
Ligesom man ikke kan kilde-henvise til &amp;quot;google&amp;quot;, for at angive at man har fundet informationer på nettet, så kan man heller ikke kildehenvise til ChatGPT direkte som en kilde.&lt;br /&gt;
&lt;br /&gt;
Når man finder informationer med google&#039;, så skal man angive hvor på nettet man har fundet dem med så præcis en kildehenvisning, at man kan se den information der er blevet anvendt.&lt;br /&gt;
&lt;br /&gt;
Denne type henvisning kan man ikke lave i forhold til ChatGPT, da sprogmodellen der ligger bag ChatGPT konstant udvikler sig, samt at de svar sprogmodellen giver har et randomiseret element indbygget, som er med til at give bedre svar&amp;lt;ref&amp;gt;[https://www.it-vest.dk/arrangementer/sig-webinar-14-marts-2024-kunstig-intelligens-og-chatgpt-hvordan-virker-det-og-skal-vi-bare-opgive-undervisning-og-eksamen Webinar om kunstig intelligens]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Her er man altså nødt til at tage andre metoder i brug, for at kunne dokumentere at man har udviklet sit produkt ordentligt og redeligt.&lt;br /&gt;
&lt;br /&gt;
==Kildehenvisninger i dokumentation==&lt;br /&gt;
Der kan være forskellige standarder for hvordan man kildehenviser i forskellige uddannelser, dette er skrevet med udgangspunkt i at man anvender Word bibliografi-værktøj og her vist med en Harvard-lignende standard&amp;lt;ref&amp;gt;[https://holstebro-htx.dk/index.php/Word_Kildeliste Kildelister] anvendt i Microsoft Word&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Normal Internet-kilde til kode===&lt;br /&gt;
I dette eksempel er der angivet hvordan man ville dokumentere at man har anvendt kode fra et bibliotek til noget hardware på en [[Arduino]]. I det tænkte eksempel er det en 4 kanals AD-konverter&amp;lt;ref&amp;gt;[https://arduinotech.dk/shop/ads1115-module-4-channel-16-bit-i2c-adc-with-pro-gain-amplifier 4 kanals AD-konverter] fra ArduinoTech&amp;lt;/ref&amp;gt;, der er købt som modul.&lt;br /&gt;
&lt;br /&gt;
For at kunne anvende modulet i koden skal der kommunikeres med modulet på en måde, som er angivet i beskrivelsen af modulet - det er dog ikke nødvendigt at sætte sig ind i den grundlæggende kommunikation, hvis man blot ønsker at få værdier ind i sin software. Som en dokumentation for hvordan man anvender biblioteket kan man skrive følgende:&lt;br /&gt;
&lt;br /&gt;
====Eksempel på dokumentation====&lt;br /&gt;
Til at hente værdierne fra den 4 kanals AD-konverter anvendes et bibliotek fundet på GitHub (Singh, 2018) som kan indlæse de analoge spændinger.&lt;br /&gt;
Til at sætte AD-konverteren rigtigt op, til at kunne læse 4 spændinger, så anvendes eksemplet ”ADS1115_SingleEnded.ino” og i setup skrives følgende kode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
    ads.getAddr_ADS1115(ADS1115_DEFAULT_ADDRESS);   // 0x48, 1001 000 (ADDR = GND)&lt;br /&gt;
    ads.setGain(GAIN_TWO);          // 2x gain   +/- 2.048V  1 bit = 0.0625mV (default)&lt;br /&gt;
    ads.setMode(MODE_CONTIN);       // Continuous conversion mode&lt;br /&gt;
    ads.setRate(RATE_128);          // 128SPS (default)&lt;br /&gt;
    ads.setOSMode(OSMODE_SINGLE);   // Set to start a single-conversion&lt;br /&gt;
    ads.begin();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
I [[loop()]] testes i første omgang, om det kan lade sig gøre at læse de 4 kanaler. Dette gøres ved at afvikle følgende testkode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
    address = ads.ads_i2cAddress;&lt;br /&gt;
    Wire.beginTransmission(address);&lt;br /&gt;
    error = Wire.endTransmission();&lt;br /&gt;
    if (error == 0)&lt;br /&gt;
    {&lt;br /&gt;
        int16_t adc0, adc1, adc2, adc3;&lt;br /&gt;
&lt;br /&gt;
        adc0 = ads.Measure_SingleEnded(0);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 1: &amp;quot;);&lt;br /&gt;
        Serial.println(adc0);&lt;br /&gt;
        adc1 = ads.Measure_SingleEnded(1);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 2: &amp;quot;);&lt;br /&gt;
        Serial.println(adc1);&lt;br /&gt;
        adc2 = ads.Measure_SingleEnded(2);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 3: &amp;quot;);&lt;br /&gt;
        Serial.println(adc2);&lt;br /&gt;
        adc3 = ads.Measure_SingleEnded(3);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 4: &amp;quot;);&lt;br /&gt;
        Serial.println(adc3);&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Denne test giver det ønskede resultat.&lt;br /&gt;
&lt;br /&gt;
Ud fra denne beskrivelse viser man, at man tager andres kode, og anvender ind i sit eget projekt, og man angiver præcist i sin beskrivelse hvad man har taget fra andres kode.&lt;br /&gt;
&lt;br /&gt;
I kildelisten vil kilden optræde på følgende måde:&lt;br /&gt;
&lt;br /&gt;
Singh, Y., 2018. Arduino Library ADS1115 16 bit 4 channel ADC. [Online] &amp;lt;br /&amp;gt;&lt;br /&gt;
Available at: https://github.com/ncdcommunity/Arduino_Library_ADS1115_16Bit_4Channel_ADC&amp;lt;br /&amp;gt;&lt;br /&gt;
[Senest hentet eller vist den 15 marts 2024].&lt;br /&gt;
&lt;br /&gt;
===ChatGPT som kilde til kode===&lt;br /&gt;
Det følgende er skrevet med udgangspunkt i det der er beskrevet på viden.ai&amp;lt;ref&amp;gt;[https://viden.ai/korrekt-kildehenvisning-af-chatgpt/ Korrekt kildehenvisning af ChatGPT]&amp;lt;/ref&amp;gt;. hvor der angives hvordan man kildehenviser, men også lidt om hvordan man håndterer det i tekst - i korte træk, lav et metodeafsnit, beskriv hvad man gør og vær meget redelig, ved at man angiver hvad man har fået af ChatGPT ved at lægge det ved som et bilag.&lt;br /&gt;
&lt;br /&gt;
Hvis man forstår at prompte fornuftigt, så er ChatGPT faktisk ret god til at foreslå kode, der kan anvendes, men ligesom det er plagiat hvis man kopierer fra nettet, så er det plagiat, hvis man lader ChatGPT skrive store dele af ens program for sig.&lt;br /&gt;
&lt;br /&gt;
Som det er formuleret i vejledningen til både programmering C og B, så kan man anvende ChatGPT til hjælp i fejlfinding af kode. For at kunne kildehenvise korrekt til hjælp med fejlfinding, så skal man angive hvad man har promptet til ChatGPT og hvad den har svaret - det kan placeres i bilag.&lt;br /&gt;
&lt;br /&gt;
En anden ting, som også er OK at få hjælp med er, at komme i gang med programmet - det er denne problematik der her gives et eksempel på. I eksemplet beskrives hvad man skal skrive i sin dokumentation, når man har anvendt denne hjælp, og der er forslag til hvordan man kommer videre i projektet.&lt;br /&gt;
&lt;br /&gt;
Konkret er det starten på udviklingen af et lille spil med bolde i et vindue, udviklet i Processing, der tages udgangspunkt i.&lt;br /&gt;
&lt;br /&gt;
====Metodeafsnit med omtale af ChatGPT====&lt;br /&gt;
Når man anvender CharGPT, så skal man dokumentere hvordan man har gjort det, og hvilke overvejelser der ligger bag det. Det betegnes i rapportskrivning som et metodeafsnit. Det kunne i dette eksempel lyde:&lt;br /&gt;
&lt;br /&gt;
For at få en fornuftig start på programkoden er der brugt ChatGPT til at få rammerne på koden etableret, og til at få et system, så der kan optræde flere bolde i programvinduet. Det er ChatGPT 3.5 (OpenAI, 2023)&amp;lt;ref&amp;gt;[https://chat.openai.com/chat Indgangen til ChatGPT 3.5]&amp;lt;/ref&amp;gt; der er anvendt til denne hjælp. Til programstarten blev der promptet efter at få et programvindue på 800x600 hvor en bold bevæger sig rundt. Den foreslåede kode blev kopieret ind i processings IDE (Processing, 2024)&amp;lt;ref&amp;gt;[https://processing.org Hovedsiden for Processing]&amp;lt;/ref&amp;gt; og testet – den opførte sig som forventet.&lt;br /&gt;
&lt;br /&gt;
Derefter blev der promptet efter at få den bold der bevægede sig til at dele sig op i to, når man klikker på den med musen. Dette resulterede i en væsentligt anderledes kode, som igen blev kopieret ind i processing og testet, og igen med et acceptabelt resultat. Dialogen med ChatGPT (OpenAI, 2023) og herunder de to koder, kan ses i bilag 1.&lt;br /&gt;
&lt;br /&gt;
Herefter er resten af koden udviklet på traditionel vis, hvor første trin var at dokumentere princippet i den foreslåede kode, specielt den Ball klasse der blev introduceret for at kunne arbejde med flere bolde i vinduet.&lt;br /&gt;
&lt;br /&gt;
Det nævnte bilag 1 [[media:ChatGPT-dialog-1.pdf|kan ses i denne PDF]].&lt;br /&gt;
&lt;br /&gt;
Når man opretter kilden i Word, så er det lidt forskelligt hvilke felter der er synlige, alt efter hvilken standard man har aktiv - men ved Harvard standarden kan indtastningerne se således ud:&lt;br /&gt;
&lt;br /&gt;
[[fil:citat-ChatGPT.png|Indtastningerne ved kildehenvisning til ChatGPT]]&amp;lt;br /&amp;gt;&#039;&#039;Indtastningerne ved kildehenvisning til ChatGPT&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Mere om teknikken i at anvende kildelister kan ses på [https://holstebro-htx.dk/index.php/Word_Kildeliste Holstebro HTX Wiki - Kildelister].&lt;br /&gt;
&lt;br /&gt;
====Dokumentation af koden udviklet af ChatGPT====&lt;br /&gt;
Da der skulle kunne dannes nye bolde så oprettes der en klasse, som ChatGPT skriver det i dialogen i Bilag 1:&lt;br /&gt;
&lt;br /&gt;
: &#039;&#039;&amp;quot;Dette kodeeksempel opretter en klasse kaldet Ball, som repræsenterer boldobjekterne. Når musen klikkes, kontrolleres det, om musens position er inden for en bold. Hvis det er tilfældet, oprettes to nye boldobjekter, der bevæger sig i forskellige retninger, og den originale bold fjernes fra arrayet.&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Ved at teste koden kan man se at det ikke er det helt rigtige den formulerer - der oprettes godt nok to nye bold-objekter, men det er ikke den oprindelige bold der fjernes, det er den ene af de ny-oprettede bolde. Det kan ses ved at de to bolde kommer i samme position, og den ene fortsætter i samme retning (den oprindelige), mens den ny-oprettede går i en tilfældig retning. Dette rettes til senere i dokumentationen under &amp;quot;oprettelse af ny bold&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
For at have en god struktur i koden, så placeres klassen Ball i en fil for sig kaldet Ball. Denne fil starter med at definere koden som en klasse med linjen:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
class Ball {&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dernæst defineres klassens egenskaber, der er boldens position og hastighed samt en fast diameter. Ud over det er der en x- og y-retning defineret. Den anvendes til at sige om bolden bevæger sig i en positiv eller negativ retning, så de skifter mellem +1 og -1, når kanterne rammes.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  float x, y;&lt;br /&gt;
  float xspeed, yspeed;&lt;br /&gt;
  int diameter = 30;&lt;br /&gt;
  int xdirection = 1;&lt;br /&gt;
  int ydirection = 1;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der defineres to forskellige constructors til bolden. Den første anvendes til at danne den første bold med, hvor position og hastighed sættes tilfældigt.&lt;br /&gt;
&lt;br /&gt;
Her forudses et problem at der kan komme et randfænomen, hvis bolden dannes, så den ligger med noget uden for skærmen. Da det er tilfældigt; så er det sjældent problemet opstår. For at fremprovokere det oftere er det testet med en diameter på 200, hvor det kunne ses at bolden bliver &amp;quot;hængende&amp;quot; i kanten.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  Ball() {&lt;br /&gt;
    x = random(width);&lt;br /&gt;
    y = random(height);&lt;br /&gt;
    xspeed = random(0.5, 2);&lt;br /&gt;
    yspeed = random(0.5, 2);&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Dette rettes ved at omskrive den foreslåede constructor til følgende kode, hvor bolden placeres mindst en halv diameter fra kanten:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  Ball() {&lt;br /&gt;
    x = random(diameter / 2, width - diameter / 2);&lt;br /&gt;
    y = random(diameter / 2, height - diameter / 2);&lt;br /&gt;
    xspeed = random(0.5, 2);&lt;br /&gt;
    yspeed = random(0.5, 2);&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Den anden constructor tager fire parametre, der er positionen og hastigheden. Denne constructor anvendes, når der skal dannes nye bolde, hvor koden netop skal starte den nye bold i den oprindelige bolds position, og med en ny retning.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  Ball(float x, float y, float xspeed, float yspeed) {&lt;br /&gt;
    this.x = x;&lt;br /&gt;
    this.y = y;&lt;br /&gt;
    this.xspeed = xspeed;&lt;br /&gt;
    this.yspeed = yspeed;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ud over disse standard ting til oprettelsen af objekter, så er der 3 metoder i klassen. Den første er en move() metode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  void move() {&lt;br /&gt;
    x = x + (xspeed * xdirection);&lt;br /&gt;
    y = y + (yspeed * ydirection);&lt;br /&gt;
&lt;br /&gt;
    if ((x + diameter/2 &amp;gt;= width) || (x - diameter/2 &amp;lt;= 0)) {&lt;br /&gt;
      xdirection *= -1;&lt;br /&gt;
    }&lt;br /&gt;
    if ((y + diameter/2 &amp;gt;= height) || (y - diameter/2 &amp;lt;= 0)) {&lt;br /&gt;
      ydirection *= -1;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Måden metoden virker på er at den lægger hastigheden til boldens position (både x og y), og hvis boldens position (både i x og y) er kommet uden for rammen, så ændres retningen for enten x eller y.&lt;br /&gt;
&lt;br /&gt;
For at kunne vise bolden er der en display() metode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  void display() {&lt;br /&gt;
    ellipse(x, y, diameter, diameter);&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Den sidste metode hedder contains(), og den tager en position som parameter til metoden. Der undersøges så om den position ligger inden for bolden ved at se om afstanden mellem boldens center og den testede position er mindre end den halve diameter. Hvis den er inden for bolden, så returneres true, ellers returneres false:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  boolean contains(float x, float y) {&lt;br /&gt;
    float d = dist(x, y, this.x, this.y);&lt;br /&gt;
    if (d &amp;lt; diameter/2) {&lt;br /&gt;
      return true;&lt;br /&gt;
    } else {&lt;br /&gt;
      return false;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Oprettelse af ny bold====&lt;br /&gt;
I den oprindelige kode undersøges om der er klikket på en bold, ved at alle bolde løbes igennem i mousePressed() funktionen, og med metoden contains undersøges om der er klikket på en bold. Denne måde at undersøge alle bolde på beholdes.&lt;br /&gt;
&lt;br /&gt;
Som omtalt er det ikke den smarteste måde til at dele bolden op i to, der anvendes. Som det ses i koden herunder, så appendes der to nye bolde på med den oprindelige bolds x- og y-position på samt tilfældige x- og y-hastigheder. Disse to bolde lægges i slutningen af arrayet. Derefter anvendes shorten&amp;lt;ref&amp;gt;[https://processing.org/reference/shorten_.html Processings shorten metode til arrays]&amp;lt;/ref&amp;gt; til at fjerne et element, men da det element der fjernes er det sidste element i arrayet, så fjernes der bare den sidst oprettede bold.&lt;br /&gt;
&lt;br /&gt;
Hvis man var tilfreds med den opførsel, så kunne man blot fjerne kodelinjen med den anden append og kodelinjen med shorten. Så ville man have samme funktion.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
    if (balls[i].contains(mouseX, mouseY)) {&lt;br /&gt;
      balls = (Ball[]) append(balls, new Ball(balls[i].x, balls[i].y, random(-5, 5), random(-5, 5)));&lt;br /&gt;
      balls = (Ball[]) append(balls, new Ball(balls[i].x, balls[i].y, random(-5, 5), random(-5, 5)));&lt;br /&gt;
      balls = (Ball[]) shorten(balls);&lt;br /&gt;
      break;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Den nye bold der oprettes får bare en tilfældig retning, og den oprindelige bold fortsætter bare i den retning den var på vej i. Det er ikke den opførsel der ønskes i spillet. Der ønskes i stedet at det ser ud som om bolden &amp;quot;splittes op&amp;quot; i 2 bolde, og den opførsel laves ved at lade den oprindelige bold ændre 30 grader til den ene side, og den nye bold får 30 grader til den anden side.&lt;br /&gt;
&lt;br /&gt;
For at gøre dette, så oprettes der en metode multiply() i klassen Ball. Denne metode returnerer en ny bold af typen Ball, så nu kan koden i museklikket skrives som følger:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
    if (balls[i].contains(mouseX, mouseY)) {&lt;br /&gt;
      balls = (Ball[]) append(balls, balls[i].multiply());&lt;br /&gt;
      break;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Som det kan ses, så appendes der en ny bold ind i balls-arrayet, ud fra metoden multiply().&lt;br /&gt;
&lt;br /&gt;
Metoden multiply() oprettes inde i klassen med følgende kode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  Ball multiply() {&lt;br /&gt;
    xspeed *= xdirection;&lt;br /&gt;
    yspeed *= ydirection;&lt;br /&gt;
    xdirection = 1;&lt;br /&gt;
    ydirection = 1;&lt;br /&gt;
    float speed = dist(0, 0, xspeed, yspeed);&lt;br /&gt;
    float angle = acos(xspeed / speed);&lt;br /&gt;
    if (yspeed &amp;lt; 0) angle = 0.0 - angle;&lt;br /&gt;
    speed *= 1.5;&lt;br /&gt;
    xspeed = speed * cos(angle + PI / 6);&lt;br /&gt;
    yspeed = speed * sin(angle + PI / 6);&lt;br /&gt;
    Ball b = new Ball(x, y, speed * cos(angle - PI / 6), speed * sin(angle - PI / 6));&lt;br /&gt;
    return b;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Først regnes retningen over i xspeed og yspeed, så de kan være både positive og negative. På den måde indeholder de to variabler retningen.&lt;br /&gt;
&lt;br /&gt;
Dernæst omregnes x- og y-hastigheden til en samlet hastighed speed og en vinkel angle, som kan være mellem +PI og -PI (+/- 180 grader).&lt;br /&gt;
&lt;br /&gt;
Begge bolde skal bevæge sig hurtigere efter de er delt, så spillet gradvist bliver sværere, derfor ganges hastigheden med 1,5.&lt;br /&gt;
&lt;br /&gt;
Den oprindelige bold får nu en ny retning, ved at udregne x- og y-hastigheden ud fra den nye hastighed og vinklen plus 30 grader.&lt;br /&gt;
&lt;br /&gt;
Til sidst oprettes en ny bold med samme position som den oprindelige og en x- og y-hastighed udregnet fra den oprindelige bolds hastighed og vinklen minus 30 grader. Denne bold returneres fra metoden.&lt;br /&gt;
&lt;br /&gt;
==Refleksioner over anvendelsen==&lt;br /&gt;
Der er selvfølgelig stadig lang vej til man har et færdigt spil, men ideen var også at tage fat i, hvordan man anvender ChatGPT på en ordentlig og redelig måde i et programmeringsprojekt. Dette kan selvfølgelig altid gradbøjes, men hvis man håndterer anvendelsen som vist i eksemplet, så vil man ikke gøre noget der kommer i nærheden af plagiat.&lt;br /&gt;
&lt;br /&gt;
==Referencer== &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt; &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Programmering}}&lt;br /&gt;
&lt;br /&gt;
[[Kategori:Programmering teknik]]&lt;/div&gt;</summary>
		<author><name>Bar</name></author>
	</entry>
	<entry>
		<id>https://www.htxarduino.dk/index.php?title=Fil:Citat-ChatGPT.png&amp;diff=5403</id>
		<title>Fil:Citat-ChatGPT.png</title>
		<link rel="alternate" type="text/html" href="https://www.htxarduino.dk/index.php?title=Fil:Citat-ChatGPT.png&amp;diff=5403"/>
		<updated>2024-03-18T20:25:35Z</updated>

		<summary type="html">&lt;p&gt;Bar: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Bar</name></author>
	</entry>
	<entry>
		<id>https://www.htxarduino.dk/index.php?title=Programmering_med_ChatGPT&amp;diff=5402</id>
		<title>Programmering med ChatGPT</title>
		<link rel="alternate" type="text/html" href="https://www.htxarduino.dk/index.php?title=Programmering_med_ChatGPT&amp;diff=5402"/>
		<updated>2024-03-18T20:25:07Z</updated>

		<summary type="html">&lt;p&gt;Bar: /* Metodeafsnit med omtale af ChatGPT */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Det er ikke så svært at få ChatGPT&amp;lt;ref&amp;gt;[https://chat.openai.com/auth/login ChatGPT Login] - Indgangen til ChatGPT&amp;lt;/ref&amp;gt; til at lave kode, der skal man blot beskrive hvad man gerne vil have programmet til at gøre, og så kopiere den kode, der kommer ud af det - det giver tit ret gode resultater.&lt;br /&gt;
&lt;br /&gt;
Problemet med at anvende ChatGPT i forbindelse med skoleprojekter er, at man skal have forståelsen med i det, og at man ikke kan blive anklaget for plagiat.&lt;br /&gt;
&lt;br /&gt;
==Hvad må man ikke i en skoleprojekt==&lt;br /&gt;
*Man må ikke kopiere kode, som man ikke selv har skrevet, til et programmeringsprodukt uden at man angiver en kilde. Det er uanset hvor koden stammer fra, også selvom man har brugt ChatGPT til at &amp;quot;udvikle&amp;quot; koden.&lt;br /&gt;
*Man må ikke aflevere et produkt hvor de primære dele af koden er kopieret, heller ikke selvom man kildehenviser.&lt;br /&gt;
*Man må ikke få ChatGPT til at dokumentere sin kode, ved at man kopierer ChatGPT&#039;s beskrivelse ind i sin dokumentation af koden.&lt;br /&gt;
&lt;br /&gt;
De beskrevne eksempler er at betragte som plagiat, og vil blive håndteret efter skolens ordensregler, hvilket i værste fald kan ende med at et fag annulleres eller man bliver bortvist fra uddannelsen.&lt;br /&gt;
==Hvad er tilladt med ChatGPT==&lt;br /&gt;
På samme måde som man må anvende kilder fra internettet, så må man i programmerings-faget i gymnasiet anvende ChatGPT i udviklingen af kode til et programmeringsprodukt. Dette er blevet tilladt via en revidering af vejledningen til faget&amp;lt;ref&amp;gt;[https://www.uvm.dk/-/media/filer/uvm/udd/gym/pdf23/aug/vejledninger/valgfag/230807-programmering-c--valgfag.pdf Vejledning] til Valgfaget Programmering C&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
I vejledningen står der som følger:&lt;br /&gt;
&lt;br /&gt;
: &#039;&#039;&amp;quot;brug af internettet er tilladt som fagligt hjælpemiddel ved de mundtlige prøver, inkluderer de tilladte hjælpemidler anvendelsen af chatbots og lignende på en måde, som afspejler, hvordan man arbejder i den daglige undervisning. Dette kunne fx være brug af ChatGPT til at debugge kode.&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Det skal altså afspejle den normale brug, som man også har ved at bruge internettet. Som angivet under hvad man ikke må, så er den normale brug, at man anvender information til at lære at programmere, men at man ikke tager så meget af sit produkt fra nettet, så man ikke har en forståelse af hvordan produktet er sammensat.&lt;br /&gt;
&lt;br /&gt;
Videre i vejledningen står der:&lt;br /&gt;
&lt;br /&gt;
: &#039;&#039;&amp;quot;I forhold til denne type hjælpemidler er det vigtigt at være opmærksom på, at den tilladte anvendelse er betinget af, at hjælpemidlerne kun benyttes i et omfang, hvor prøvebesvarelsen er selvstændig og udelukkende elevens egen.&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Igen understreges at det der afleveres skal være elevens selvstændigt udviklede produkt og dokumentation, hvor man på normal vis anvender internettet som et værktøj til at bibringe forståelse.&lt;br /&gt;
&lt;br /&gt;
==Problemet med ChatGPT==&lt;br /&gt;
Ligesom man ikke kan kilde-henvise til &amp;quot;google&amp;quot;, for at angive at man har fundet informationer på nettet, så kan man heller ikke kildehenvise til ChatGPT direkte som en kilde.&lt;br /&gt;
&lt;br /&gt;
Når man finder informationer med google&#039;, så skal man angive hvor på nettet man har fundet dem med så præcis en kildehenvisning, at man kan se den information der er blevet anvendt.&lt;br /&gt;
&lt;br /&gt;
Denne type henvisning kan man ikke lave i forhold til ChatGPT, da sprogmodellen der ligger bag ChatGPT konstant udvikler sig, samt at de svar sprogmodellen giver har et randomiseret element indbygget, som er med til at give bedre svar&amp;lt;ref&amp;gt;[https://www.it-vest.dk/arrangementer/sig-webinar-14-marts-2024-kunstig-intelligens-og-chatgpt-hvordan-virker-det-og-skal-vi-bare-opgive-undervisning-og-eksamen Webinar om kunstig intelligens]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Her er man altså nødt til at tage andre metoder i brug, for at kunne dokumentere at man har udviklet sit produkt ordentligt og redeligt.&lt;br /&gt;
&lt;br /&gt;
==Kildehenvisninger i dokumentation==&lt;br /&gt;
Der kan være forskellige standarder for hvordan man kildehenviser i forskellige uddannelser, dette er skrevet med udgangspunkt i at man anvender Word bibliografi-værktøj og her vist med en Harvard-lignende standard&amp;lt;ref&amp;gt;[https://holstebro-htx.dk/index.php/Word_Kildeliste Kildelister] anvendt i Microsoft Word&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Normal Internet-kilde til kode===&lt;br /&gt;
I dette eksempel er der angivet hvordan man ville dokumentere at man har anvendt kode fra et bibliotek til noget hardware på en [[Arduino]]. I det tænkte eksempel er det en 4 kanals AD-konverter&amp;lt;ref&amp;gt;[https://arduinotech.dk/shop/ads1115-module-4-channel-16-bit-i2c-adc-with-pro-gain-amplifier 4 kanals AD-konverter] fra ArduinoTech&amp;lt;/ref&amp;gt;, der er købt som modul.&lt;br /&gt;
&lt;br /&gt;
For at kunne anvende modulet i koden skal der kommunikeres med modulet på en måde, som er angivet i beskrivelsen af modulet - det er dog ikke nødvendigt at sætte sig ind i den grundlæggende kommunikation, hvis man blot ønsker at få værdier ind i sin software. Som en dokumentation for hvordan man anvender biblioteket kan man skrive følgende:&lt;br /&gt;
&lt;br /&gt;
====Eksempel på dokumentation====&lt;br /&gt;
Til at hente værdierne fra den 4 kanals AD-konverter anvendes et bibliotek fundet på GitHub (Singh, 2018) som kan indlæse de analoge spændinger.&lt;br /&gt;
Til at sætte AD-konverteren rigtigt op, til at kunne læse 4 spændinger, så anvendes eksemplet ”ADS1115_SingleEnded.ino” og i setup skrives følgende kode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
    ads.getAddr_ADS1115(ADS1115_DEFAULT_ADDRESS);   // 0x48, 1001 000 (ADDR = GND)&lt;br /&gt;
    ads.setGain(GAIN_TWO);          // 2x gain   +/- 2.048V  1 bit = 0.0625mV (default)&lt;br /&gt;
    ads.setMode(MODE_CONTIN);       // Continuous conversion mode&lt;br /&gt;
    ads.setRate(RATE_128);          // 128SPS (default)&lt;br /&gt;
    ads.setOSMode(OSMODE_SINGLE);   // Set to start a single-conversion&lt;br /&gt;
    ads.begin();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
I [[loop()]] testes i første omgang, om det kan lade sig gøre at læse de 4 kanaler. Dette gøres ved at afvikle følgende testkode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
    address = ads.ads_i2cAddress;&lt;br /&gt;
    Wire.beginTransmission(address);&lt;br /&gt;
    error = Wire.endTransmission();&lt;br /&gt;
    if (error == 0)&lt;br /&gt;
    {&lt;br /&gt;
        int16_t adc0, adc1, adc2, adc3;&lt;br /&gt;
&lt;br /&gt;
        adc0 = ads.Measure_SingleEnded(0);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 1: &amp;quot;);&lt;br /&gt;
        Serial.println(adc0);&lt;br /&gt;
        adc1 = ads.Measure_SingleEnded(1);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 2: &amp;quot;);&lt;br /&gt;
        Serial.println(adc1);&lt;br /&gt;
        adc2 = ads.Measure_SingleEnded(2);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 3: &amp;quot;);&lt;br /&gt;
        Serial.println(adc2);&lt;br /&gt;
        adc3 = ads.Measure_SingleEnded(3);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 4: &amp;quot;);&lt;br /&gt;
        Serial.println(adc3);&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Denne test giver det ønskede resultat.&lt;br /&gt;
&lt;br /&gt;
Ud fra denne beskrivelse viser man, at man tager andres kode, og anvender ind i sit eget projekt, og man angiver præcist i sin beskrivelse hvad man har taget fra andres kode.&lt;br /&gt;
&lt;br /&gt;
I kildelisten vil kilden optræde på følgende måde:&lt;br /&gt;
&lt;br /&gt;
Singh, Y., 2018. Arduino Library ADS1115 16 bit 4 channel ADC. [Online] &amp;lt;br /&amp;gt;&lt;br /&gt;
Available at: https://github.com/ncdcommunity/Arduino_Library_ADS1115_16Bit_4Channel_ADC&amp;lt;br /&amp;gt;&lt;br /&gt;
[Senest hentet eller vist den 15 marts 2024].&lt;br /&gt;
&lt;br /&gt;
===ChatGPT som kilde til kode===&lt;br /&gt;
Det følgende er skrevet med udgangspunkt i det der er beskrevet på viden.ai&amp;lt;ref&amp;gt;[https://viden.ai/korrekt-kildehenvisning-af-chatgpt/ Korrekt kildehenvisning af ChatGPT]&amp;lt;/ref&amp;gt;. hvor der angives hvordan man kildehenviser, men også lidt om hvordan man håndterer det i tekst - i korte træk, lav et metodeafsnit, beskriv hvad man gør og vær meget redelig, ved at man angiver hvad man har fået af ChatGPT ved at lægge det ved som et bilag.&lt;br /&gt;
&lt;br /&gt;
Hvis man forstår at prompte fornuftigt, så er ChatGPT faktisk ret god til at foreslå kode, der kan anvendes, men ligesom det er plagiat hvis man kopierer fra nettet, så er det plagiat, hvis man lader ChatGPT skrive store dele af ens program for sig.&lt;br /&gt;
&lt;br /&gt;
Som det er formuleret i vejledningen til både programmering C og B, så kan man anvende ChatGPT til hjælp i fejlfinding af kode. For at kunne kildehenvise korrekt til hjælp med fejlfinding, så skal man angive hvad man har promptet til ChatGPT og hvad den har svaret - det kan placeres i bilag.&lt;br /&gt;
&lt;br /&gt;
En anden ting, som også er OK at få hjælp med er, at komme i gang med programmet - det er denne problematik der her gives et eksempel på. I eksemplet beskrives hvad man skal skrive i sin dokumentation, når man har anvendt denne hjælp, og der er forslag til hvordan man kommer videre i projektet.&lt;br /&gt;
&lt;br /&gt;
Konkret er det starten på udviklingen af et lille spil med bolde i et vindue, udviklet i Processing, der tages udgangspunkt i.&lt;br /&gt;
&lt;br /&gt;
====Metodeafsnit med omtale af ChatGPT====&lt;br /&gt;
Når man anvender CharGPT, så skal man dokumentere hvordan man har gjort det, og hvilke overvejelser der ligger bag det. Det betegnes i rapportskrivning som et metodeafsnit. Det kunne i dette eksempel lyde:&lt;br /&gt;
&lt;br /&gt;
For at få en fornuftig start på programkoden er der brugt ChatGPT til at få rammerne på koden etableret, og til at få et system, så der kan optræde flere bolde i programvinduet. Det er ChatGPT 3.5 (OpenAI, 2023)&amp;lt;ref&amp;gt;[https://chat.openai.com/chat Indgangen til ChatGPT 3.5]&amp;lt;/ref&amp;gt; der er anvendt til denne hjælp. Til programstarten blev der promptet efter at få et programvindue på 800x600 hvor en bold bevæger sig rundt. Den foreslåede kode blev kopieret ind i processings IDE (Processing, 2024)&amp;lt;ref&amp;gt;[https://processing.org Hovedsiden for Processing]&amp;lt;/ref&amp;gt; og testet – den opførte sig som forventet.&lt;br /&gt;
&lt;br /&gt;
Derefter blev der promptet efter at få den bold der bevægede sig til at dele sig op i to, når man klikker på den med musen. Dette resulterede i en væsentligt anderledes kode, som igen blev kopieret ind i processing og testet, og igen med et acceptabelt resultat. Dialogen med ChatGPT (OpenAI, 2023) og herunder de to koder, kan ses i bilag 1.&lt;br /&gt;
&lt;br /&gt;
Herefter er resten af koden udviklet på traditionel vis, hvor første trin var at dokumentere princippet i den foreslåede kode, specielt den Ball klasse der blev introduceret for at kunne arbejde med flere bolde i vinduet.&lt;br /&gt;
&lt;br /&gt;
Det nævnte bilag 1 [[media:ChatGPT-dialog-1.pdf|kan ses i denne PDF]].&lt;br /&gt;
&lt;br /&gt;
Når man opretter kilden i Word, så er det lidt forskelligt hvilke felter der er synlige, alt efter hvilken standard man har aktiv - men ved Harvard standarden kan indtastningerne se således ud:&lt;br /&gt;
&lt;br /&gt;
[[fil:citat-ChatGPT.png|Indtastningerne ved kildehenvisning til ChatGPT]]&amp;lt;br /&amp;gt;&#039;&#039;Indtastningerne ved kildehenvisning til ChatGPT&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
====Dokumentation af koden udviklet af ChatGPT====&lt;br /&gt;
Da der skulle kunne dannes nye bolde så oprettes der en klasse, som ChatGPT skriver det i dialogen i Bilag 1:&lt;br /&gt;
&lt;br /&gt;
: &#039;&#039;&amp;quot;Dette kodeeksempel opretter en klasse kaldet Ball, som repræsenterer boldobjekterne. Når musen klikkes, kontrolleres det, om musens position er inden for en bold. Hvis det er tilfældet, oprettes to nye boldobjekter, der bevæger sig i forskellige retninger, og den originale bold fjernes fra arrayet.&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Ved at teste koden kan man se at det ikke er det helt rigtige den formulerer - der oprettes godt nok to nye bold-objekter, men det er ikke den oprindelige bold der fjernes, det er den ene af de ny-oprettede bolde. Det kan ses ved at de to bolde kommer i samme position, og den ene fortsætter i samme retning (den oprindelige), mens den ny-oprettede går i en tilfældig retning. Dette rettes til senere i dokumentationen under &amp;quot;oprettelse af ny bold&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
For at have en god struktur i koden, så placeres klassen Ball i en fil for sig kaldet Ball. Denne fil starter med at definere koden som en klasse med linjen:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
class Ball {&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dernæst defineres klassens egenskaber, der er boldens position og hastighed samt en fast diameter. Ud over det er der en x- og y-retning defineret. Den anvendes til at sige om bolden bevæger sig i en positiv eller negativ retning, så de skifter mellem +1 og -1, når kanterne rammes.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  float x, y;&lt;br /&gt;
  float xspeed, yspeed;&lt;br /&gt;
  int diameter = 30;&lt;br /&gt;
  int xdirection = 1;&lt;br /&gt;
  int ydirection = 1;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der defineres to forskellige constructors til bolden. Den første anvendes til at danne den første bold med, hvor position og hastighed sættes tilfældigt.&lt;br /&gt;
&lt;br /&gt;
Her forudses et problem at der kan komme et randfænomen, hvis bolden dannes, så den ligger med noget uden for skærmen. Da det er tilfældigt; så er det sjældent problemet opstår. For at fremprovokere det oftere er det testet med en diameter på 200, hvor det kunne ses at bolden bliver &amp;quot;hængende&amp;quot; i kanten.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  Ball() {&lt;br /&gt;
    x = random(width);&lt;br /&gt;
    y = random(height);&lt;br /&gt;
    xspeed = random(0.5, 2);&lt;br /&gt;
    yspeed = random(0.5, 2);&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Dette rettes ved at omskrive den foreslåede constructor til følgende kode, hvor bolden placeres mindst en halv diameter fra kanten:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  Ball() {&lt;br /&gt;
    x = random(diameter / 2, width - diameter / 2);&lt;br /&gt;
    y = random(diameter / 2, height - diameter / 2);&lt;br /&gt;
    xspeed = random(0.5, 2);&lt;br /&gt;
    yspeed = random(0.5, 2);&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Den anden constructor tager fire parametre, der er positionen og hastigheden. Denne constructor anvendes, når der skal dannes nye bolde, hvor koden netop skal starte den nye bold i den oprindelige bolds position, og med en ny retning.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  Ball(float x, float y, float xspeed, float yspeed) {&lt;br /&gt;
    this.x = x;&lt;br /&gt;
    this.y = y;&lt;br /&gt;
    this.xspeed = xspeed;&lt;br /&gt;
    this.yspeed = yspeed;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ud over disse standard ting til oprettelsen af objekter, så er der 3 metoder i klassen. Den første er en move() metode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  void move() {&lt;br /&gt;
    x = x + (xspeed * xdirection);&lt;br /&gt;
    y = y + (yspeed * ydirection);&lt;br /&gt;
&lt;br /&gt;
    if ((x + diameter/2 &amp;gt;= width) || (x - diameter/2 &amp;lt;= 0)) {&lt;br /&gt;
      xdirection *= -1;&lt;br /&gt;
    }&lt;br /&gt;
    if ((y + diameter/2 &amp;gt;= height) || (y - diameter/2 &amp;lt;= 0)) {&lt;br /&gt;
      ydirection *= -1;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Måden metoden virker på er at den lægger hastigheden til boldens position (både x og y), og hvis boldens position (både i x og y) er kommet uden for rammen, så ændres retningen for enten x eller y.&lt;br /&gt;
&lt;br /&gt;
For at kunne vise bolden er der en display() metode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  void display() {&lt;br /&gt;
    ellipse(x, y, diameter, diameter);&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Den sidste metode hedder contains(), og den tager en position som parameter til metoden. Der undersøges så om den position ligger inden for bolden ved at se om afstanden mellem boldens center og den testede position er mindre end den halve diameter. Hvis den er inden for bolden, så returneres true, ellers returneres false:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  boolean contains(float x, float y) {&lt;br /&gt;
    float d = dist(x, y, this.x, this.y);&lt;br /&gt;
    if (d &amp;lt; diameter/2) {&lt;br /&gt;
      return true;&lt;br /&gt;
    } else {&lt;br /&gt;
      return false;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Oprettelse af ny bold====&lt;br /&gt;
I den oprindelige kode undersøges om der er klikket på en bold, ved at alle bolde løbes igennem i mousePressed() funktionen, og med metoden contains undersøges om der er klikket på en bold. Denne måde at undersøge alle bolde på beholdes.&lt;br /&gt;
&lt;br /&gt;
Som omtalt er det ikke den smarteste måde til at dele bolden op i to, der anvendes. Som det ses i koden herunder, så appendes der to nye bolde på med den oprindelige bolds x- og y-position på samt tilfældige x- og y-hastigheder. Disse to bolde lægges i slutningen af arrayet. Derefter anvendes shorten&amp;lt;ref&amp;gt;[https://processing.org/reference/shorten_.html Processings shorten metode til arrays]&amp;lt;/ref&amp;gt; til at fjerne et element, men da det element der fjernes er det sidste element i arrayet, så fjernes der bare den sidst oprettede bold.&lt;br /&gt;
&lt;br /&gt;
Hvis man var tilfreds med den opførsel, så kunne man blot fjerne kodelinjen med den anden append og kodelinjen med shorten. Så ville man have samme funktion.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
    if (balls[i].contains(mouseX, mouseY)) {&lt;br /&gt;
      balls = (Ball[]) append(balls, new Ball(balls[i].x, balls[i].y, random(-5, 5), random(-5, 5)));&lt;br /&gt;
      balls = (Ball[]) append(balls, new Ball(balls[i].x, balls[i].y, random(-5, 5), random(-5, 5)));&lt;br /&gt;
      balls = (Ball[]) shorten(balls);&lt;br /&gt;
      break;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Den nye bold der oprettes får bare en tilfældig retning, og den oprindelige bold fortsætter bare i den retning den var på vej i. Det er ikke den opførsel der ønskes i spillet. Der ønskes i stedet at det ser ud som om bolden &amp;quot;splittes op&amp;quot; i 2 bolde, og den opførsel laves ved at lade den oprindelige bold ændre 30 grader til den ene side, og den nye bold får 30 grader til den anden side.&lt;br /&gt;
&lt;br /&gt;
For at gøre dette, så oprettes der en metode multiply() i klassen Ball. Denne metode returnerer en ny bold af typen Ball, så nu kan koden i museklikket skrives som følger:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
    if (balls[i].contains(mouseX, mouseY)) {&lt;br /&gt;
      balls = (Ball[]) append(balls, balls[i].multiply());&lt;br /&gt;
      break;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Som det kan ses, så appendes der en ny bold ind i balls-arrayet, ud fra metoden multiply().&lt;br /&gt;
&lt;br /&gt;
Metoden multiply() oprettes inde i klassen med følgende kode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  Ball multiply() {&lt;br /&gt;
    xspeed *= xdirection;&lt;br /&gt;
    yspeed *= ydirection;&lt;br /&gt;
    xdirection = 1;&lt;br /&gt;
    ydirection = 1;&lt;br /&gt;
    float speed = dist(0, 0, xspeed, yspeed);&lt;br /&gt;
    float angle = acos(xspeed / speed);&lt;br /&gt;
    if (yspeed &amp;lt; 0) angle = 0.0 - angle;&lt;br /&gt;
    speed *= 1.5;&lt;br /&gt;
    xspeed = speed * cos(angle + PI / 6);&lt;br /&gt;
    yspeed = speed * sin(angle + PI / 6);&lt;br /&gt;
    Ball b = new Ball(x, y, speed * cos(angle - PI / 6), speed * sin(angle - PI / 6));&lt;br /&gt;
    return b;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Først regnes retningen over i xspeed og yspeed, så de kan være både positive og negative. På den måde indeholder de to variabler retningen.&lt;br /&gt;
&lt;br /&gt;
Dernæst omregnes x- og y-hastigheden til en samlet hastighed speed og en vinkel angle, som kan være mellem +PI og -PI (+/- 180 grader).&lt;br /&gt;
&lt;br /&gt;
Begge bolde skal bevæge sig hurtigere efter de er delt, så spillet gradvist bliver sværere, derfor ganges hastigheden med 1,5.&lt;br /&gt;
&lt;br /&gt;
Den oprindelige bold får nu en ny retning, ved at udregne x- og y-hastigheden ud fra den nye hastighed og vinklen plus 30 grader.&lt;br /&gt;
&lt;br /&gt;
Til sidst oprettes en ny bold med samme position som den oprindelige og en x- og y-hastighed udregnet fra den oprindelige bolds hastighed og vinklen minus 30 grader. Denne bold returneres fra metoden.&lt;br /&gt;
&lt;br /&gt;
==Refleksioner over anvendelsen==&lt;br /&gt;
Der er selvfølgelig stadig lang vej til man har et færdigt spil, men ideen var også at tage fat i, hvordan man anvender ChatGPT på en ordentlig og redelig måde i et programmeringsprojekt. Dette kan selvfølgelig altid gradbøjes, men hvis man håndterer anvendelsen som vist i eksemplet, så vil man ikke gøre noget der kommer i nærheden af plagiat.&lt;br /&gt;
&lt;br /&gt;
==Referencer== &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt; &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Programmering}}&lt;br /&gt;
&lt;br /&gt;
[[Kategori:Programmering teknik]]&lt;/div&gt;</summary>
		<author><name>Bar</name></author>
	</entry>
	<entry>
		<id>https://www.htxarduino.dk/index.php?title=Programmering_med_ChatGPT&amp;diff=5401</id>
		<title>Programmering med ChatGPT</title>
		<link rel="alternate" type="text/html" href="https://www.htxarduino.dk/index.php?title=Programmering_med_ChatGPT&amp;diff=5401"/>
		<updated>2024-03-18T13:02:44Z</updated>

		<summary type="html">&lt;p&gt;Bar: /* Hvad er tilladt med ChatGPT */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Det er ikke så svært at få ChatGPT&amp;lt;ref&amp;gt;[https://chat.openai.com/auth/login ChatGPT Login] - Indgangen til ChatGPT&amp;lt;/ref&amp;gt; til at lave kode, der skal man blot beskrive hvad man gerne vil have programmet til at gøre, og så kopiere den kode, der kommer ud af det - det giver tit ret gode resultater.&lt;br /&gt;
&lt;br /&gt;
Problemet med at anvende ChatGPT i forbindelse med skoleprojekter er, at man skal have forståelsen med i det, og at man ikke kan blive anklaget for plagiat.&lt;br /&gt;
&lt;br /&gt;
==Hvad må man ikke i en skoleprojekt==&lt;br /&gt;
*Man må ikke kopiere kode, som man ikke selv har skrevet, til et programmeringsprodukt uden at man angiver en kilde. Det er uanset hvor koden stammer fra, også selvom man har brugt ChatGPT til at &amp;quot;udvikle&amp;quot; koden.&lt;br /&gt;
*Man må ikke aflevere et produkt hvor de primære dele af koden er kopieret, heller ikke selvom man kildehenviser.&lt;br /&gt;
*Man må ikke få ChatGPT til at dokumentere sin kode, ved at man kopierer ChatGPT&#039;s beskrivelse ind i sin dokumentation af koden.&lt;br /&gt;
&lt;br /&gt;
De beskrevne eksempler er at betragte som plagiat, og vil blive håndteret efter skolens ordensregler, hvilket i værste fald kan ende med at et fag annulleres eller man bliver bortvist fra uddannelsen.&lt;br /&gt;
==Hvad er tilladt med ChatGPT==&lt;br /&gt;
På samme måde som man må anvende kilder fra internettet, så må man i programmerings-faget i gymnasiet anvende ChatGPT i udviklingen af kode til et programmeringsprodukt. Dette er blevet tilladt via en revidering af vejledningen til faget&amp;lt;ref&amp;gt;[https://www.uvm.dk/-/media/filer/uvm/udd/gym/pdf23/aug/vejledninger/valgfag/230807-programmering-c--valgfag.pdf Vejledning] til Valgfaget Programmering C&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
I vejledningen står der som følger:&lt;br /&gt;
&lt;br /&gt;
: &#039;&#039;&amp;quot;brug af internettet er tilladt som fagligt hjælpemiddel ved de mundtlige prøver, inkluderer de tilladte hjælpemidler anvendelsen af chatbots og lignende på en måde, som afspejler, hvordan man arbejder i den daglige undervisning. Dette kunne fx være brug af ChatGPT til at debugge kode.&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Det skal altså afspejle den normale brug, som man også har ved at bruge internettet. Som angivet under hvad man ikke må, så er den normale brug, at man anvender information til at lære at programmere, men at man ikke tager så meget af sit produkt fra nettet, så man ikke har en forståelse af hvordan produktet er sammensat.&lt;br /&gt;
&lt;br /&gt;
Videre i vejledningen står der:&lt;br /&gt;
&lt;br /&gt;
: &#039;&#039;&amp;quot;I forhold til denne type hjælpemidler er det vigtigt at være opmærksom på, at den tilladte anvendelse er betinget af, at hjælpemidlerne kun benyttes i et omfang, hvor prøvebesvarelsen er selvstændig og udelukkende elevens egen.&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Igen understreges at det der afleveres skal være elevens selvstændigt udviklede produkt og dokumentation, hvor man på normal vis anvender internettet som et værktøj til at bibringe forståelse.&lt;br /&gt;
&lt;br /&gt;
==Problemet med ChatGPT==&lt;br /&gt;
Ligesom man ikke kan kilde-henvise til &amp;quot;google&amp;quot;, for at angive at man har fundet informationer på nettet, så kan man heller ikke kildehenvise til ChatGPT direkte som en kilde.&lt;br /&gt;
&lt;br /&gt;
Når man finder informationer med google&#039;, så skal man angive hvor på nettet man har fundet dem med så præcis en kildehenvisning, at man kan se den information der er blevet anvendt.&lt;br /&gt;
&lt;br /&gt;
Denne type henvisning kan man ikke lave i forhold til ChatGPT, da sprogmodellen der ligger bag ChatGPT konstant udvikler sig, samt at de svar sprogmodellen giver har et randomiseret element indbygget, som er med til at give bedre svar&amp;lt;ref&amp;gt;[https://www.it-vest.dk/arrangementer/sig-webinar-14-marts-2024-kunstig-intelligens-og-chatgpt-hvordan-virker-det-og-skal-vi-bare-opgive-undervisning-og-eksamen Webinar om kunstig intelligens]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Her er man altså nødt til at tage andre metoder i brug, for at kunne dokumentere at man har udviklet sit produkt ordentligt og redeligt.&lt;br /&gt;
&lt;br /&gt;
==Kildehenvisninger i dokumentation==&lt;br /&gt;
Der kan være forskellige standarder for hvordan man kildehenviser i forskellige uddannelser, dette er skrevet med udgangspunkt i at man anvender Word bibliografi-værktøj og her vist med en Harvard-lignende standard&amp;lt;ref&amp;gt;[https://holstebro-htx.dk/index.php/Word_Kildeliste Kildelister] anvendt i Microsoft Word&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Normal Internet-kilde til kode===&lt;br /&gt;
I dette eksempel er der angivet hvordan man ville dokumentere at man har anvendt kode fra et bibliotek til noget hardware på en [[Arduino]]. I det tænkte eksempel er det en 4 kanals AD-konverter&amp;lt;ref&amp;gt;[https://arduinotech.dk/shop/ads1115-module-4-channel-16-bit-i2c-adc-with-pro-gain-amplifier 4 kanals AD-konverter] fra ArduinoTech&amp;lt;/ref&amp;gt;, der er købt som modul.&lt;br /&gt;
&lt;br /&gt;
For at kunne anvende modulet i koden skal der kommunikeres med modulet på en måde, som er angivet i beskrivelsen af modulet - det er dog ikke nødvendigt at sætte sig ind i den grundlæggende kommunikation, hvis man blot ønsker at få værdier ind i sin software. Som en dokumentation for hvordan man anvender biblioteket kan man skrive følgende:&lt;br /&gt;
&lt;br /&gt;
====Eksempel på dokumentation====&lt;br /&gt;
Til at hente værdierne fra den 4 kanals AD-konverter anvendes et bibliotek fundet på GitHub (Singh, 2018) som kan indlæse de analoge spændinger.&lt;br /&gt;
Til at sætte AD-konverteren rigtigt op, til at kunne læse 4 spændinger, så anvendes eksemplet ”ADS1115_SingleEnded.ino” og i setup skrives følgende kode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
    ads.getAddr_ADS1115(ADS1115_DEFAULT_ADDRESS);   // 0x48, 1001 000 (ADDR = GND)&lt;br /&gt;
    ads.setGain(GAIN_TWO);          // 2x gain   +/- 2.048V  1 bit = 0.0625mV (default)&lt;br /&gt;
    ads.setMode(MODE_CONTIN);       // Continuous conversion mode&lt;br /&gt;
    ads.setRate(RATE_128);          // 128SPS (default)&lt;br /&gt;
    ads.setOSMode(OSMODE_SINGLE);   // Set to start a single-conversion&lt;br /&gt;
    ads.begin();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
I [[loop()]] testes i første omgang, om det kan lade sig gøre at læse de 4 kanaler. Dette gøres ved at afvikle følgende testkode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
    address = ads.ads_i2cAddress;&lt;br /&gt;
    Wire.beginTransmission(address);&lt;br /&gt;
    error = Wire.endTransmission();&lt;br /&gt;
    if (error == 0)&lt;br /&gt;
    {&lt;br /&gt;
        int16_t adc0, adc1, adc2, adc3;&lt;br /&gt;
&lt;br /&gt;
        adc0 = ads.Measure_SingleEnded(0);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 1: &amp;quot;);&lt;br /&gt;
        Serial.println(adc0);&lt;br /&gt;
        adc1 = ads.Measure_SingleEnded(1);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 2: &amp;quot;);&lt;br /&gt;
        Serial.println(adc1);&lt;br /&gt;
        adc2 = ads.Measure_SingleEnded(2);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 3: &amp;quot;);&lt;br /&gt;
        Serial.println(adc2);&lt;br /&gt;
        adc3 = ads.Measure_SingleEnded(3);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 4: &amp;quot;);&lt;br /&gt;
        Serial.println(adc3);&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Denne test giver det ønskede resultat.&lt;br /&gt;
&lt;br /&gt;
Ud fra denne beskrivelse viser man, at man tager andres kode, og anvender ind i sit eget projekt, og man angiver præcist i sin beskrivelse hvad man har taget fra andres kode.&lt;br /&gt;
&lt;br /&gt;
I kildelisten vil kilden optræde på følgende måde:&lt;br /&gt;
&lt;br /&gt;
Singh, Y., 2018. Arduino Library ADS1115 16 bit 4 channel ADC. [Online] &amp;lt;br /&amp;gt;&lt;br /&gt;
Available at: https://github.com/ncdcommunity/Arduino_Library_ADS1115_16Bit_4Channel_ADC&amp;lt;br /&amp;gt;&lt;br /&gt;
[Senest hentet eller vist den 15 marts 2024].&lt;br /&gt;
&lt;br /&gt;
===ChatGPT som kilde til kode===&lt;br /&gt;
Det følgende er skrevet med udgangspunkt i det der er beskrevet på viden.ai&amp;lt;ref&amp;gt;[https://viden.ai/korrekt-kildehenvisning-af-chatgpt/ Korrekt kildehenvisning af ChatGPT]&amp;lt;/ref&amp;gt;. hvor der angives hvordan man kildehenviser, men også lidt om hvordan man håndterer det i tekst - i korte træk, lav et metodeafsnit, beskriv hvad man gør og vær meget redelig, ved at man angiver hvad man har fået af ChatGPT ved at lægge det ved som et bilag.&lt;br /&gt;
&lt;br /&gt;
Hvis man forstår at prompte fornuftigt, så er ChatGPT faktisk ret god til at foreslå kode, der kan anvendes, men ligesom det er plagiat hvis man kopierer fra nettet, så er det plagiat, hvis man lader ChatGPT skrive store dele af ens program for sig.&lt;br /&gt;
&lt;br /&gt;
Som det er formuleret i vejledningen til både programmering C og B, så kan man anvende ChatGPT til hjælp i fejlfinding af kode. For at kunne kildehenvise korrekt til hjælp med fejlfinding, så skal man angive hvad man har promptet til ChatGPT og hvad den har svaret - det kan placeres i bilag.&lt;br /&gt;
&lt;br /&gt;
En anden ting, som også er OK at få hjælp med er, at komme i gang med programmet - det er denne problematik der her gives et eksempel på. I eksemplet beskrives hvad man skal skrive i sin dokumentation, når man har anvendt denne hjælp, og der er forslag til hvordan man kommer videre i projektet.&lt;br /&gt;
&lt;br /&gt;
Konkret er det starten på udviklingen af et lille spil med bolde i et vindue, udviklet i Processing, der tages udgangspunkt i.&lt;br /&gt;
&lt;br /&gt;
====Metodeafsnit med omtale af ChatGPT====&lt;br /&gt;
Når man anvender CharGPT, så skal man dokumentere hvordan man har gjort det, og hvilke overvejelser der ligger bag det. Det betegnes i rapportskrivning som et metodeafsnit. Det kunne i dette eksempel lyde:&lt;br /&gt;
&lt;br /&gt;
For at få en fornuftig start på programkoden er der brugt ChatGPT til at få rammerne på koden etableret, og til at få et system, så der kan optræde flere bolde i programvinduet. Det er ChatGPT 3.5 (OpenAI, 2023)&amp;lt;ref&amp;gt;[https://chat.openai.com/chat Indgangen til ChatGPT 3.5]&amp;lt;/ref&amp;gt; der er anvendt til denne hjælp. Til programstarten blev der promptet efter at få et programvindue på 800x600 hvor en bold bevæger sig rundt. Den foreslåede kode blev kopieret ind i processings IDE (Processing, 2024)&amp;lt;ref&amp;gt;[https://processing.org Hovedsiden for Processing]&amp;lt;/ref&amp;gt; og testet – den opførte sig som forventet.&lt;br /&gt;
&lt;br /&gt;
Derefter blev der promptet efter at få den bold der bevægede sig til at dele sig op i to, når man klikker på den med musen. Dette resulterede i en væsentligt anderledes kode, som igen blev kopieret ind i processing og testet, og igen med et acceptabelt resultat. Dialogen med ChatGPT (OpenAI, 2023) og herunder de to koder, kan ses i bilag 1.&lt;br /&gt;
&lt;br /&gt;
Herefter er resten af koden udviklet på traditionel vis, hvor første trin var at dokumentere princippet i den foreslåede kode, specielt den Ball klasse der blev introduceret for at kunne arbejde med flere bolde i vinduet.&lt;br /&gt;
&lt;br /&gt;
Det nævnte bilag 1 [[media:ChatGPT-dialog-1.pdf|kan ses i denne PDF]].&lt;br /&gt;
&lt;br /&gt;
====Dokumentation af koden udviklet af ChatGPT====&lt;br /&gt;
Da der skulle kunne dannes nye bolde så oprettes der en klasse, som ChatGPT skriver det i dialogen i Bilag 1:&lt;br /&gt;
&lt;br /&gt;
: &#039;&#039;&amp;quot;Dette kodeeksempel opretter en klasse kaldet Ball, som repræsenterer boldobjekterne. Når musen klikkes, kontrolleres det, om musens position er inden for en bold. Hvis det er tilfældet, oprettes to nye boldobjekter, der bevæger sig i forskellige retninger, og den originale bold fjernes fra arrayet.&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Ved at teste koden kan man se at det ikke er det helt rigtige den formulerer - der oprettes godt nok to nye bold-objekter, men det er ikke den oprindelige bold der fjernes, det er den ene af de ny-oprettede bolde. Det kan ses ved at de to bolde kommer i samme position, og den ene fortsætter i samme retning (den oprindelige), mens den ny-oprettede går i en tilfældig retning. Dette rettes til senere i dokumentationen under &amp;quot;oprettelse af ny bold&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
For at have en god struktur i koden, så placeres klassen Ball i en fil for sig kaldet Ball. Denne fil starter med at definere koden som en klasse med linjen:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
class Ball {&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dernæst defineres klassens egenskaber, der er boldens position og hastighed samt en fast diameter. Ud over det er der en x- og y-retning defineret. Den anvendes til at sige om bolden bevæger sig i en positiv eller negativ retning, så de skifter mellem +1 og -1, når kanterne rammes.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  float x, y;&lt;br /&gt;
  float xspeed, yspeed;&lt;br /&gt;
  int diameter = 30;&lt;br /&gt;
  int xdirection = 1;&lt;br /&gt;
  int ydirection = 1;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der defineres to forskellige constructors til bolden. Den første anvendes til at danne den første bold med, hvor position og hastighed sættes tilfældigt.&lt;br /&gt;
&lt;br /&gt;
Her forudses et problem at der kan komme et randfænomen, hvis bolden dannes, så den ligger med noget uden for skærmen. Da det er tilfældigt; så er det sjældent problemet opstår. For at fremprovokere det oftere er det testet med en diameter på 200, hvor det kunne ses at bolden bliver &amp;quot;hængende&amp;quot; i kanten.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  Ball() {&lt;br /&gt;
    x = random(width);&lt;br /&gt;
    y = random(height);&lt;br /&gt;
    xspeed = random(0.5, 2);&lt;br /&gt;
    yspeed = random(0.5, 2);&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Dette rettes ved at omskrive den foreslåede constructor til følgende kode, hvor bolden placeres mindst en halv diameter fra kanten:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  Ball() {&lt;br /&gt;
    x = random(diameter / 2, width - diameter / 2);&lt;br /&gt;
    y = random(diameter / 2, height - diameter / 2);&lt;br /&gt;
    xspeed = random(0.5, 2);&lt;br /&gt;
    yspeed = random(0.5, 2);&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Den anden constructor tager fire parametre, der er positionen og hastigheden. Denne constructor anvendes, når der skal dannes nye bolde, hvor koden netop skal starte den nye bold i den oprindelige bolds position, og med en ny retning.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  Ball(float x, float y, float xspeed, float yspeed) {&lt;br /&gt;
    this.x = x;&lt;br /&gt;
    this.y = y;&lt;br /&gt;
    this.xspeed = xspeed;&lt;br /&gt;
    this.yspeed = yspeed;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ud over disse standard ting til oprettelsen af objekter, så er der 3 metoder i klassen. Den første er en move() metode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  void move() {&lt;br /&gt;
    x = x + (xspeed * xdirection);&lt;br /&gt;
    y = y + (yspeed * ydirection);&lt;br /&gt;
&lt;br /&gt;
    if ((x + diameter/2 &amp;gt;= width) || (x - diameter/2 &amp;lt;= 0)) {&lt;br /&gt;
      xdirection *= -1;&lt;br /&gt;
    }&lt;br /&gt;
    if ((y + diameter/2 &amp;gt;= height) || (y - diameter/2 &amp;lt;= 0)) {&lt;br /&gt;
      ydirection *= -1;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Måden metoden virker på er at den lægger hastigheden til boldens position (både x og y), og hvis boldens position (både i x og y) er kommet uden for rammen, så ændres retningen for enten x eller y.&lt;br /&gt;
&lt;br /&gt;
For at kunne vise bolden er der en display() metode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  void display() {&lt;br /&gt;
    ellipse(x, y, diameter, diameter);&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Den sidste metode hedder contains(), og den tager en position som parameter til metoden. Der undersøges så om den position ligger inden for bolden ved at se om afstanden mellem boldens center og den testede position er mindre end den halve diameter. Hvis den er inden for bolden, så returneres true, ellers returneres false:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  boolean contains(float x, float y) {&lt;br /&gt;
    float d = dist(x, y, this.x, this.y);&lt;br /&gt;
    if (d &amp;lt; diameter/2) {&lt;br /&gt;
      return true;&lt;br /&gt;
    } else {&lt;br /&gt;
      return false;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Oprettelse af ny bold====&lt;br /&gt;
I den oprindelige kode undersøges om der er klikket på en bold, ved at alle bolde løbes igennem i mousePressed() funktionen, og med metoden contains undersøges om der er klikket på en bold. Denne måde at undersøge alle bolde på beholdes.&lt;br /&gt;
&lt;br /&gt;
Som omtalt er det ikke den smarteste måde til at dele bolden op i to, der anvendes. Som det ses i koden herunder, så appendes der to nye bolde på med den oprindelige bolds x- og y-position på samt tilfældige x- og y-hastigheder. Disse to bolde lægges i slutningen af arrayet. Derefter anvendes shorten&amp;lt;ref&amp;gt;[https://processing.org/reference/shorten_.html Processings shorten metode til arrays]&amp;lt;/ref&amp;gt; til at fjerne et element, men da det element der fjernes er det sidste element i arrayet, så fjernes der bare den sidst oprettede bold.&lt;br /&gt;
&lt;br /&gt;
Hvis man var tilfreds med den opførsel, så kunne man blot fjerne kodelinjen med den anden append og kodelinjen med shorten. Så ville man have samme funktion.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
    if (balls[i].contains(mouseX, mouseY)) {&lt;br /&gt;
      balls = (Ball[]) append(balls, new Ball(balls[i].x, balls[i].y, random(-5, 5), random(-5, 5)));&lt;br /&gt;
      balls = (Ball[]) append(balls, new Ball(balls[i].x, balls[i].y, random(-5, 5), random(-5, 5)));&lt;br /&gt;
      balls = (Ball[]) shorten(balls);&lt;br /&gt;
      break;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Den nye bold der oprettes får bare en tilfældig retning, og den oprindelige bold fortsætter bare i den retning den var på vej i. Det er ikke den opførsel der ønskes i spillet. Der ønskes i stedet at det ser ud som om bolden &amp;quot;splittes op&amp;quot; i 2 bolde, og den opførsel laves ved at lade den oprindelige bold ændre 30 grader til den ene side, og den nye bold får 30 grader til den anden side.&lt;br /&gt;
&lt;br /&gt;
For at gøre dette, så oprettes der en metode multiply() i klassen Ball. Denne metode returnerer en ny bold af typen Ball, så nu kan koden i museklikket skrives som følger:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
    if (balls[i].contains(mouseX, mouseY)) {&lt;br /&gt;
      balls = (Ball[]) append(balls, balls[i].multiply());&lt;br /&gt;
      break;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Som det kan ses, så appendes der en ny bold ind i balls-arrayet, ud fra metoden multiply().&lt;br /&gt;
&lt;br /&gt;
Metoden multiply() oprettes inde i klassen med følgende kode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  Ball multiply() {&lt;br /&gt;
    xspeed *= xdirection;&lt;br /&gt;
    yspeed *= ydirection;&lt;br /&gt;
    xdirection = 1;&lt;br /&gt;
    ydirection = 1;&lt;br /&gt;
    float speed = dist(0, 0, xspeed, yspeed);&lt;br /&gt;
    float angle = acos(xspeed / speed);&lt;br /&gt;
    if (yspeed &amp;lt; 0) angle = 0.0 - angle;&lt;br /&gt;
    speed *= 1.5;&lt;br /&gt;
    xspeed = speed * cos(angle + PI / 6);&lt;br /&gt;
    yspeed = speed * sin(angle + PI / 6);&lt;br /&gt;
    Ball b = new Ball(x, y, speed * cos(angle - PI / 6), speed * sin(angle - PI / 6));&lt;br /&gt;
    return b;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Først regnes retningen over i xspeed og yspeed, så de kan være både positive og negative. På den måde indeholder de to variabler retningen.&lt;br /&gt;
&lt;br /&gt;
Dernæst omregnes x- og y-hastigheden til en samlet hastighed speed og en vinkel angle, som kan være mellem +PI og -PI (+/- 180 grader).&lt;br /&gt;
&lt;br /&gt;
Begge bolde skal bevæge sig hurtigere efter de er delt, så spillet gradvist bliver sværere, derfor ganges hastigheden med 1,5.&lt;br /&gt;
&lt;br /&gt;
Den oprindelige bold får nu en ny retning, ved at udregne x- og y-hastigheden ud fra den nye hastighed og vinklen plus 30 grader.&lt;br /&gt;
&lt;br /&gt;
Til sidst oprettes en ny bold med samme position som den oprindelige og en x- og y-hastighed udregnet fra den oprindelige bolds hastighed og vinklen minus 30 grader. Denne bold returneres fra metoden.&lt;br /&gt;
&lt;br /&gt;
==Refleksioner over anvendelsen==&lt;br /&gt;
Der er selvfølgelig stadig lang vej til man har et færdigt spil, men ideen var også at tage fat i, hvordan man anvender ChatGPT på en ordentlig og redelig måde i et programmeringsprojekt. Dette kan selvfølgelig altid gradbøjes, men hvis man håndterer anvendelsen som vist i eksemplet, så vil man ikke gøre noget der kommer i nærheden af plagiat.&lt;br /&gt;
&lt;br /&gt;
==Referencer== &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt; &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Programmering}}&lt;br /&gt;
&lt;br /&gt;
[[Kategori:Programmering teknik]]&lt;/div&gt;</summary>
		<author><name>Bar</name></author>
	</entry>
	<entry>
		<id>https://www.htxarduino.dk/index.php?title=Programmering_med_ChatGPT&amp;diff=5400</id>
		<title>Programmering med ChatGPT</title>
		<link rel="alternate" type="text/html" href="https://www.htxarduino.dk/index.php?title=Programmering_med_ChatGPT&amp;diff=5400"/>
		<updated>2024-03-17T08:35:49Z</updated>

		<summary type="html">&lt;p&gt;Bar: /* Refleksioner over anvendelsen */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Det er ikke så svært at få ChatGPT&amp;lt;ref&amp;gt;[https://chat.openai.com/auth/login ChatGPT Login] - Indgangen til ChatGPT&amp;lt;/ref&amp;gt; til at lave kode, der skal man blot beskrive hvad man gerne vil have programmet til at gøre, og så kopiere den kode, der kommer ud af det - det giver tit ret gode resultater.&lt;br /&gt;
&lt;br /&gt;
Problemet med at anvende ChatGPT i forbindelse med skoleprojekter er, at man skal have forståelsen med i det, og at man ikke kan blive anklaget for plagiat.&lt;br /&gt;
&lt;br /&gt;
==Hvad må man ikke i en skoleprojekt==&lt;br /&gt;
*Man må ikke kopiere kode, som man ikke selv har skrevet, til et programmeringsprodukt uden at man angiver en kilde. Det er uanset hvor koden stammer fra, også selvom man har brugt ChatGPT til at &amp;quot;udvikle&amp;quot; koden.&lt;br /&gt;
*Man må ikke aflevere et produkt hvor de primære dele af koden er kopieret, heller ikke selvom man kildehenviser.&lt;br /&gt;
*Man må ikke få ChatGPT til at dokumentere sin kode, ved at man kopierer ChatGPT&#039;s beskrivelse ind i sin dokumentation af koden.&lt;br /&gt;
&lt;br /&gt;
De beskrevne eksempler er at betragte som plagiat, og vil blive håndteret efter skolens ordensregler, hvilket i værste fald kan ende med at et fag annulleres eller man bliver bortvist fra uddannelsen.&lt;br /&gt;
==Hvad er tilladt med ChatGPT==&lt;br /&gt;
På samme måde som man må anvende kilder fra internettet, så må man i programmerings-faget i gymnasiet anvende ChatGPT i udviklingen af kode til et programmeringsprodukt. Dette er blevet tilladt via en revidering af vejledningen til faget&amp;lt;ref&amp;gt;[https://www.uvm.dk/-/media/filer/uvm/udd/gym/pdf23/aug/vejledninger/valgfag/230807-programmering-c--valgfag.pdf Vejledning] til Valgfaget Programmering C&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
I vejledningen står der som følger:&lt;br /&gt;
&lt;br /&gt;
: &#039;&#039;&amp;quot;brug af internettet er tilladt som fagligt hjælpemiddel ved de mundtlige prøver, inkluderer de tilladte hjælpemidler anvendelsen af chatbots og lignende på en måde, som afspejler, hvordan man arbejder i den daglige undervisning. Dette kunne fx være brug af ChatGPT til at debugge kode.&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Det skal altså afspejle den normale brug, som man også har ved at bruge internettet. Som angivet under hvad man ikke må, så er den normale brug, at man anvender information til at lære et programmere, men at man ikke tager så meget af sit produkt fra nettet, så man ikke har en forståelse af hvordan produktet er sammensat.&lt;br /&gt;
&lt;br /&gt;
Videre i vejledningen står der:&lt;br /&gt;
&lt;br /&gt;
: &#039;&#039;&amp;quot;I forhold til denne type hjælpemidler er det vigtigt at være opmærksom på, at den tilladte anvendelse er betinget af, at hjælpemidlerne kun benyttes i et omfang, hvor prøvebesvarelsen er selvstændig og udelukkende elevens egen.&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Igen understreges at det der afleveres skal være elevens selvstændigt udviklede produkt og dokumentation, hvor man på normal vis anvender internettet som et værktøj til at bibringe forståelse.&lt;br /&gt;
&lt;br /&gt;
==Problemet med ChatGPT==&lt;br /&gt;
Ligesom man ikke kan kilde-henvise til &amp;quot;google&amp;quot;, for at angive at man har fundet informationer på nettet, så kan man heller ikke kildehenvise til ChatGPT direkte som en kilde.&lt;br /&gt;
&lt;br /&gt;
Når man finder informationer med google&#039;, så skal man angive hvor på nettet man har fundet dem med så præcis en kildehenvisning, at man kan se den information der er blevet anvendt.&lt;br /&gt;
&lt;br /&gt;
Denne type henvisning kan man ikke lave i forhold til ChatGPT, da sprogmodellen der ligger bag ChatGPT konstant udvikler sig, samt at de svar sprogmodellen giver har et randomiseret element indbygget, som er med til at give bedre svar&amp;lt;ref&amp;gt;[https://www.it-vest.dk/arrangementer/sig-webinar-14-marts-2024-kunstig-intelligens-og-chatgpt-hvordan-virker-det-og-skal-vi-bare-opgive-undervisning-og-eksamen Webinar om kunstig intelligens]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Her er man altså nødt til at tage andre metoder i brug, for at kunne dokumentere at man har udviklet sit produkt ordentligt og redeligt.&lt;br /&gt;
&lt;br /&gt;
==Kildehenvisninger i dokumentation==&lt;br /&gt;
Der kan være forskellige standarder for hvordan man kildehenviser i forskellige uddannelser, dette er skrevet med udgangspunkt i at man anvender Word bibliografi-værktøj og her vist med en Harvard-lignende standard&amp;lt;ref&amp;gt;[https://holstebro-htx.dk/index.php/Word_Kildeliste Kildelister] anvendt i Microsoft Word&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Normal Internet-kilde til kode===&lt;br /&gt;
I dette eksempel er der angivet hvordan man ville dokumentere at man har anvendt kode fra et bibliotek til noget hardware på en [[Arduino]]. I det tænkte eksempel er det en 4 kanals AD-konverter&amp;lt;ref&amp;gt;[https://arduinotech.dk/shop/ads1115-module-4-channel-16-bit-i2c-adc-with-pro-gain-amplifier 4 kanals AD-konverter] fra ArduinoTech&amp;lt;/ref&amp;gt;, der er købt som modul.&lt;br /&gt;
&lt;br /&gt;
For at kunne anvende modulet i koden skal der kommunikeres med modulet på en måde, som er angivet i beskrivelsen af modulet - det er dog ikke nødvendigt at sætte sig ind i den grundlæggende kommunikation, hvis man blot ønsker at få værdier ind i sin software. Som en dokumentation for hvordan man anvender biblioteket kan man skrive følgende:&lt;br /&gt;
&lt;br /&gt;
====Eksempel på dokumentation====&lt;br /&gt;
Til at hente værdierne fra den 4 kanals AD-konverter anvendes et bibliotek fundet på GitHub (Singh, 2018) som kan indlæse de analoge spændinger.&lt;br /&gt;
Til at sætte AD-konverteren rigtigt op, til at kunne læse 4 spændinger, så anvendes eksemplet ”ADS1115_SingleEnded.ino” og i setup skrives følgende kode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
    ads.getAddr_ADS1115(ADS1115_DEFAULT_ADDRESS);   // 0x48, 1001 000 (ADDR = GND)&lt;br /&gt;
    ads.setGain(GAIN_TWO);          // 2x gain   +/- 2.048V  1 bit = 0.0625mV (default)&lt;br /&gt;
    ads.setMode(MODE_CONTIN);       // Continuous conversion mode&lt;br /&gt;
    ads.setRate(RATE_128);          // 128SPS (default)&lt;br /&gt;
    ads.setOSMode(OSMODE_SINGLE);   // Set to start a single-conversion&lt;br /&gt;
    ads.begin();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
I [[loop()]] testes i første omgang, om det kan lade sig gøre at læse de 4 kanaler. Dette gøres ved at afvikle følgende testkode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
    address = ads.ads_i2cAddress;&lt;br /&gt;
    Wire.beginTransmission(address);&lt;br /&gt;
    error = Wire.endTransmission();&lt;br /&gt;
    if (error == 0)&lt;br /&gt;
    {&lt;br /&gt;
        int16_t adc0, adc1, adc2, adc3;&lt;br /&gt;
&lt;br /&gt;
        adc0 = ads.Measure_SingleEnded(0);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 1: &amp;quot;);&lt;br /&gt;
        Serial.println(adc0);&lt;br /&gt;
        adc1 = ads.Measure_SingleEnded(1);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 2: &amp;quot;);&lt;br /&gt;
        Serial.println(adc1);&lt;br /&gt;
        adc2 = ads.Measure_SingleEnded(2);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 3: &amp;quot;);&lt;br /&gt;
        Serial.println(adc2);&lt;br /&gt;
        adc3 = ads.Measure_SingleEnded(3);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 4: &amp;quot;);&lt;br /&gt;
        Serial.println(adc3);&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Denne test giver det ønskede resultat.&lt;br /&gt;
&lt;br /&gt;
Ud fra denne beskrivelse viser man, at man tager andres kode, og anvender ind i sit eget projekt, og man angiver præcist i sin beskrivelse hvad man har taget fra andres kode.&lt;br /&gt;
&lt;br /&gt;
I kildelisten vil kilden optræde på følgende måde:&lt;br /&gt;
&lt;br /&gt;
Singh, Y., 2018. Arduino Library ADS1115 16 bit 4 channel ADC. [Online] &amp;lt;br /&amp;gt;&lt;br /&gt;
Available at: https://github.com/ncdcommunity/Arduino_Library_ADS1115_16Bit_4Channel_ADC&amp;lt;br /&amp;gt;&lt;br /&gt;
[Senest hentet eller vist den 15 marts 2024].&lt;br /&gt;
&lt;br /&gt;
===ChatGPT som kilde til kode===&lt;br /&gt;
Det følgende er skrevet med udgangspunkt i det der er beskrevet på viden.ai&amp;lt;ref&amp;gt;[https://viden.ai/korrekt-kildehenvisning-af-chatgpt/ Korrekt kildehenvisning af ChatGPT]&amp;lt;/ref&amp;gt;. hvor der angives hvordan man kildehenviser, men også lidt om hvordan man håndterer det i tekst - i korte træk, lav et metodeafsnit, beskriv hvad man gør og vær meget redelig, ved at man angiver hvad man har fået af ChatGPT ved at lægge det ved som et bilag.&lt;br /&gt;
&lt;br /&gt;
Hvis man forstår at prompte fornuftigt, så er ChatGPT faktisk ret god til at foreslå kode, der kan anvendes, men ligesom det er plagiat hvis man kopierer fra nettet, så er det plagiat, hvis man lader ChatGPT skrive store dele af ens program for sig.&lt;br /&gt;
&lt;br /&gt;
Som det er formuleret i vejledningen til både programmering C og B, så kan man anvende ChatGPT til hjælp i fejlfinding af kode. For at kunne kildehenvise korrekt til hjælp med fejlfinding, så skal man angive hvad man har promptet til ChatGPT og hvad den har svaret - det kan placeres i bilag.&lt;br /&gt;
&lt;br /&gt;
En anden ting, som også er OK at få hjælp med er, at komme i gang med programmet - det er denne problematik der her gives et eksempel på. I eksemplet beskrives hvad man skal skrive i sin dokumentation, når man har anvendt denne hjælp, og der er forslag til hvordan man kommer videre i projektet.&lt;br /&gt;
&lt;br /&gt;
Konkret er det starten på udviklingen af et lille spil med bolde i et vindue, udviklet i Processing, der tages udgangspunkt i.&lt;br /&gt;
&lt;br /&gt;
====Metodeafsnit med omtale af ChatGPT====&lt;br /&gt;
Når man anvender CharGPT, så skal man dokumentere hvordan man har gjort det, og hvilke overvejelser der ligger bag det. Det betegnes i rapportskrivning som et metodeafsnit. Det kunne i dette eksempel lyde:&lt;br /&gt;
&lt;br /&gt;
For at få en fornuftig start på programkoden er der brugt ChatGPT til at få rammerne på koden etableret, og til at få et system, så der kan optræde flere bolde i programvinduet. Det er ChatGPT 3.5 (OpenAI, 2023)&amp;lt;ref&amp;gt;[https://chat.openai.com/chat Indgangen til ChatGPT 3.5]&amp;lt;/ref&amp;gt; der er anvendt til denne hjælp. Til programstarten blev der promptet efter at få et programvindue på 800x600 hvor en bold bevæger sig rundt. Den foreslåede kode blev kopieret ind i processings IDE (Processing, 2024)&amp;lt;ref&amp;gt;[https://processing.org Hovedsiden for Processing]&amp;lt;/ref&amp;gt; og testet – den opførte sig som forventet.&lt;br /&gt;
&lt;br /&gt;
Derefter blev der promptet efter at få den bold der bevægede sig til at dele sig op i to, når man klikker på den med musen. Dette resulterede i en væsentligt anderledes kode, som igen blev kopieret ind i processing og testet, og igen med et acceptabelt resultat. Dialogen med ChatGPT (OpenAI, 2023) og herunder de to koder, kan ses i bilag 1.&lt;br /&gt;
&lt;br /&gt;
Herefter er resten af koden udviklet på traditionel vis, hvor første trin var at dokumentere princippet i den foreslåede kode, specielt den Ball klasse der blev introduceret for at kunne arbejde med flere bolde i vinduet.&lt;br /&gt;
&lt;br /&gt;
Det nævnte bilag 1 [[media:ChatGPT-dialog-1.pdf|kan ses i denne PDF]].&lt;br /&gt;
&lt;br /&gt;
====Dokumentation af koden udviklet af ChatGPT====&lt;br /&gt;
Da der skulle kunne dannes nye bolde så oprettes der en klasse, som ChatGPT skriver det i dialogen i Bilag 1:&lt;br /&gt;
&lt;br /&gt;
: &#039;&#039;&amp;quot;Dette kodeeksempel opretter en klasse kaldet Ball, som repræsenterer boldobjekterne. Når musen klikkes, kontrolleres det, om musens position er inden for en bold. Hvis det er tilfældet, oprettes to nye boldobjekter, der bevæger sig i forskellige retninger, og den originale bold fjernes fra arrayet.&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Ved at teste koden kan man se at det ikke er det helt rigtige den formulerer - der oprettes godt nok to nye bold-objekter, men det er ikke den oprindelige bold der fjernes, det er den ene af de ny-oprettede bolde. Det kan ses ved at de to bolde kommer i samme position, og den ene fortsætter i samme retning (den oprindelige), mens den ny-oprettede går i en tilfældig retning. Dette rettes til senere i dokumentationen under &amp;quot;oprettelse af ny bold&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
For at have en god struktur i koden, så placeres klassen Ball i en fil for sig kaldet Ball. Denne fil starter med at definere koden som en klasse med linjen:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
class Ball {&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dernæst defineres klassens egenskaber, der er boldens position og hastighed samt en fast diameter. Ud over det er der en x- og y-retning defineret. Den anvendes til at sige om bolden bevæger sig i en positiv eller negativ retning, så de skifter mellem +1 og -1, når kanterne rammes.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  float x, y;&lt;br /&gt;
  float xspeed, yspeed;&lt;br /&gt;
  int diameter = 30;&lt;br /&gt;
  int xdirection = 1;&lt;br /&gt;
  int ydirection = 1;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der defineres to forskellige constructors til bolden. Den første anvendes til at danne den første bold med, hvor position og hastighed sættes tilfældigt.&lt;br /&gt;
&lt;br /&gt;
Her forudses et problem at der kan komme et randfænomen, hvis bolden dannes, så den ligger med noget uden for skærmen. Da det er tilfældigt; så er det sjældent problemet opstår. For at fremprovokere det oftere er det testet med en diameter på 200, hvor det kunne ses at bolden bliver &amp;quot;hængende&amp;quot; i kanten.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  Ball() {&lt;br /&gt;
    x = random(width);&lt;br /&gt;
    y = random(height);&lt;br /&gt;
    xspeed = random(0.5, 2);&lt;br /&gt;
    yspeed = random(0.5, 2);&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Dette rettes ved at omskrive den foreslåede constructor til følgende kode, hvor bolden placeres mindst en halv diameter fra kanten:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  Ball() {&lt;br /&gt;
    x = random(diameter / 2, width - diameter / 2);&lt;br /&gt;
    y = random(diameter / 2, height - diameter / 2);&lt;br /&gt;
    xspeed = random(0.5, 2);&lt;br /&gt;
    yspeed = random(0.5, 2);&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Den anden constructor tager fire parametre, der er positionen og hastigheden. Denne constructor anvendes, når der skal dannes nye bolde, hvor koden netop skal starte den nye bold i den oprindelige bolds position, og med en ny retning.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  Ball(float x, float y, float xspeed, float yspeed) {&lt;br /&gt;
    this.x = x;&lt;br /&gt;
    this.y = y;&lt;br /&gt;
    this.xspeed = xspeed;&lt;br /&gt;
    this.yspeed = yspeed;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ud over disse standard ting til oprettelsen af objekter, så er der 3 metoder i klassen. Den første er en move() metode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  void move() {&lt;br /&gt;
    x = x + (xspeed * xdirection);&lt;br /&gt;
    y = y + (yspeed * ydirection);&lt;br /&gt;
&lt;br /&gt;
    if ((x + diameter/2 &amp;gt;= width) || (x - diameter/2 &amp;lt;= 0)) {&lt;br /&gt;
      xdirection *= -1;&lt;br /&gt;
    }&lt;br /&gt;
    if ((y + diameter/2 &amp;gt;= height) || (y - diameter/2 &amp;lt;= 0)) {&lt;br /&gt;
      ydirection *= -1;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Måden metoden virker på er at den lægger hastigheden til boldens position (både x og y), og hvis boldens position (både i x og y) er kommet uden for rammen, så ændres retningen for enten x eller y.&lt;br /&gt;
&lt;br /&gt;
For at kunne vise bolden er der en display() metode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  void display() {&lt;br /&gt;
    ellipse(x, y, diameter, diameter);&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Den sidste metode hedder contains(), og den tager en position som parameter til metoden. Der undersøges så om den position ligger inden for bolden ved at se om afstanden mellem boldens center og den testede position er mindre end den halve diameter. Hvis den er inden for bolden, så returneres true, ellers returneres false:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  boolean contains(float x, float y) {&lt;br /&gt;
    float d = dist(x, y, this.x, this.y);&lt;br /&gt;
    if (d &amp;lt; diameter/2) {&lt;br /&gt;
      return true;&lt;br /&gt;
    } else {&lt;br /&gt;
      return false;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Oprettelse af ny bold====&lt;br /&gt;
I den oprindelige kode undersøges om der er klikket på en bold, ved at alle bolde løbes igennem i mousePressed() funktionen, og med metoden contains undersøges om der er klikket på en bold. Denne måde at undersøge alle bolde på beholdes.&lt;br /&gt;
&lt;br /&gt;
Som omtalt er det ikke den smarteste måde til at dele bolden op i to, der anvendes. Som det ses i koden herunder, så appendes der to nye bolde på med den oprindelige bolds x- og y-position på samt tilfældige x- og y-hastigheder. Disse to bolde lægges i slutningen af arrayet. Derefter anvendes shorten&amp;lt;ref&amp;gt;[https://processing.org/reference/shorten_.html Processings shorten metode til arrays]&amp;lt;/ref&amp;gt; til at fjerne et element, men da det element der fjernes er det sidste element i arrayet, så fjernes der bare den sidst oprettede bold.&lt;br /&gt;
&lt;br /&gt;
Hvis man var tilfreds med den opførsel, så kunne man blot fjerne kodelinjen med den anden append og kodelinjen med shorten. Så ville man have samme funktion.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
    if (balls[i].contains(mouseX, mouseY)) {&lt;br /&gt;
      balls = (Ball[]) append(balls, new Ball(balls[i].x, balls[i].y, random(-5, 5), random(-5, 5)));&lt;br /&gt;
      balls = (Ball[]) append(balls, new Ball(balls[i].x, balls[i].y, random(-5, 5), random(-5, 5)));&lt;br /&gt;
      balls = (Ball[]) shorten(balls);&lt;br /&gt;
      break;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Den nye bold der oprettes får bare en tilfældig retning, og den oprindelige bold fortsætter bare i den retning den var på vej i. Det er ikke den opførsel der ønskes i spillet. Der ønskes i stedet at det ser ud som om bolden &amp;quot;splittes op&amp;quot; i 2 bolde, og den opførsel laves ved at lade den oprindelige bold ændre 30 grader til den ene side, og den nye bold får 30 grader til den anden side.&lt;br /&gt;
&lt;br /&gt;
For at gøre dette, så oprettes der en metode multiply() i klassen Ball. Denne metode returnerer en ny bold af typen Ball, så nu kan koden i museklikket skrives som følger:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
    if (balls[i].contains(mouseX, mouseY)) {&lt;br /&gt;
      balls = (Ball[]) append(balls, balls[i].multiply());&lt;br /&gt;
      break;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Som det kan ses, så appendes der en ny bold ind i balls-arrayet, ud fra metoden multiply().&lt;br /&gt;
&lt;br /&gt;
Metoden multiply() oprettes inde i klassen med følgende kode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  Ball multiply() {&lt;br /&gt;
    xspeed *= xdirection;&lt;br /&gt;
    yspeed *= ydirection;&lt;br /&gt;
    xdirection = 1;&lt;br /&gt;
    ydirection = 1;&lt;br /&gt;
    float speed = dist(0, 0, xspeed, yspeed);&lt;br /&gt;
    float angle = acos(xspeed / speed);&lt;br /&gt;
    if (yspeed &amp;lt; 0) angle = 0.0 - angle;&lt;br /&gt;
    speed *= 1.5;&lt;br /&gt;
    xspeed = speed * cos(angle + PI / 6);&lt;br /&gt;
    yspeed = speed * sin(angle + PI / 6);&lt;br /&gt;
    Ball b = new Ball(x, y, speed * cos(angle - PI / 6), speed * sin(angle - PI / 6));&lt;br /&gt;
    return b;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Først regnes retningen over i xspeed og yspeed, så de kan være både positive og negative. På den måde indeholder de to variabler retningen.&lt;br /&gt;
&lt;br /&gt;
Dernæst omregnes x- og y-hastigheden til en samlet hastighed speed og en vinkel angle, som kan være mellem +PI og -PI (+/- 180 grader).&lt;br /&gt;
&lt;br /&gt;
Begge bolde skal bevæge sig hurtigere efter de er delt, så spillet gradvist bliver sværere, derfor ganges hastigheden med 1,5.&lt;br /&gt;
&lt;br /&gt;
Den oprindelige bold får nu en ny retning, ved at udregne x- og y-hastigheden ud fra den nye hastighed og vinklen plus 30 grader.&lt;br /&gt;
&lt;br /&gt;
Til sidst oprettes en ny bold med samme position som den oprindelige og en x- og y-hastighed udregnet fra den oprindelige bolds hastighed og vinklen minus 30 grader. Denne bold returneres fra metoden.&lt;br /&gt;
&lt;br /&gt;
==Refleksioner over anvendelsen==&lt;br /&gt;
Der er selvfølgelig stadig lang vej til man har et færdigt spil, men ideen var også at tage fat i, hvordan man anvender ChatGPT på en ordentlig og redelig måde i et programmeringsprojekt. Dette kan selvfølgelig altid gradbøjes, men hvis man håndterer anvendelsen som vist i eksemplet, så vil man ikke gøre noget der kommer i nærheden af plagiat.&lt;br /&gt;
&lt;br /&gt;
==Referencer== &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt; &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Programmering}}&lt;br /&gt;
&lt;br /&gt;
[[Kategori:Programmering teknik]]&lt;/div&gt;</summary>
		<author><name>Bar</name></author>
	</entry>
	<entry>
		<id>https://www.htxarduino.dk/index.php?title=Programmering_med_ChatGPT&amp;diff=5399</id>
		<title>Programmering med ChatGPT</title>
		<link rel="alternate" type="text/html" href="https://www.htxarduino.dk/index.php?title=Programmering_med_ChatGPT&amp;diff=5399"/>
		<updated>2024-03-17T08:34:57Z</updated>

		<summary type="html">&lt;p&gt;Bar: /* Referencer */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Det er ikke så svært at få ChatGPT&amp;lt;ref&amp;gt;[https://chat.openai.com/auth/login ChatGPT Login] - Indgangen til ChatGPT&amp;lt;/ref&amp;gt; til at lave kode, der skal man blot beskrive hvad man gerne vil have programmet til at gøre, og så kopiere den kode, der kommer ud af det - det giver tit ret gode resultater.&lt;br /&gt;
&lt;br /&gt;
Problemet med at anvende ChatGPT i forbindelse med skoleprojekter er, at man skal have forståelsen med i det, og at man ikke kan blive anklaget for plagiat.&lt;br /&gt;
&lt;br /&gt;
==Hvad må man ikke i en skoleprojekt==&lt;br /&gt;
*Man må ikke kopiere kode, som man ikke selv har skrevet, til et programmeringsprodukt uden at man angiver en kilde. Det er uanset hvor koden stammer fra, også selvom man har brugt ChatGPT til at &amp;quot;udvikle&amp;quot; koden.&lt;br /&gt;
*Man må ikke aflevere et produkt hvor de primære dele af koden er kopieret, heller ikke selvom man kildehenviser.&lt;br /&gt;
*Man må ikke få ChatGPT til at dokumentere sin kode, ved at man kopierer ChatGPT&#039;s beskrivelse ind i sin dokumentation af koden.&lt;br /&gt;
&lt;br /&gt;
De beskrevne eksempler er at betragte som plagiat, og vil blive håndteret efter skolens ordensregler, hvilket i værste fald kan ende med at et fag annulleres eller man bliver bortvist fra uddannelsen.&lt;br /&gt;
==Hvad er tilladt med ChatGPT==&lt;br /&gt;
På samme måde som man må anvende kilder fra internettet, så må man i programmerings-faget i gymnasiet anvende ChatGPT i udviklingen af kode til et programmeringsprodukt. Dette er blevet tilladt via en revidering af vejledningen til faget&amp;lt;ref&amp;gt;[https://www.uvm.dk/-/media/filer/uvm/udd/gym/pdf23/aug/vejledninger/valgfag/230807-programmering-c--valgfag.pdf Vejledning] til Valgfaget Programmering C&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
I vejledningen står der som følger:&lt;br /&gt;
&lt;br /&gt;
: &#039;&#039;&amp;quot;brug af internettet er tilladt som fagligt hjælpemiddel ved de mundtlige prøver, inkluderer de tilladte hjælpemidler anvendelsen af chatbots og lignende på en måde, som afspejler, hvordan man arbejder i den daglige undervisning. Dette kunne fx være brug af ChatGPT til at debugge kode.&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Det skal altså afspejle den normale brug, som man også har ved at bruge internettet. Som angivet under hvad man ikke må, så er den normale brug, at man anvender information til at lære et programmere, men at man ikke tager så meget af sit produkt fra nettet, så man ikke har en forståelse af hvordan produktet er sammensat.&lt;br /&gt;
&lt;br /&gt;
Videre i vejledningen står der:&lt;br /&gt;
&lt;br /&gt;
: &#039;&#039;&amp;quot;I forhold til denne type hjælpemidler er det vigtigt at være opmærksom på, at den tilladte anvendelse er betinget af, at hjælpemidlerne kun benyttes i et omfang, hvor prøvebesvarelsen er selvstændig og udelukkende elevens egen.&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Igen understreges at det der afleveres skal være elevens selvstændigt udviklede produkt og dokumentation, hvor man på normal vis anvender internettet som et værktøj til at bibringe forståelse.&lt;br /&gt;
&lt;br /&gt;
==Problemet med ChatGPT==&lt;br /&gt;
Ligesom man ikke kan kilde-henvise til &amp;quot;google&amp;quot;, for at angive at man har fundet informationer på nettet, så kan man heller ikke kildehenvise til ChatGPT direkte som en kilde.&lt;br /&gt;
&lt;br /&gt;
Når man finder informationer med google&#039;, så skal man angive hvor på nettet man har fundet dem med så præcis en kildehenvisning, at man kan se den information der er blevet anvendt.&lt;br /&gt;
&lt;br /&gt;
Denne type henvisning kan man ikke lave i forhold til ChatGPT, da sprogmodellen der ligger bag ChatGPT konstant udvikler sig, samt at de svar sprogmodellen giver har et randomiseret element indbygget, som er med til at give bedre svar&amp;lt;ref&amp;gt;[https://www.it-vest.dk/arrangementer/sig-webinar-14-marts-2024-kunstig-intelligens-og-chatgpt-hvordan-virker-det-og-skal-vi-bare-opgive-undervisning-og-eksamen Webinar om kunstig intelligens]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Her er man altså nødt til at tage andre metoder i brug, for at kunne dokumentere at man har udviklet sit produkt ordentligt og redeligt.&lt;br /&gt;
&lt;br /&gt;
==Kildehenvisninger i dokumentation==&lt;br /&gt;
Der kan være forskellige standarder for hvordan man kildehenviser i forskellige uddannelser, dette er skrevet med udgangspunkt i at man anvender Word bibliografi-værktøj og her vist med en Harvard-lignende standard&amp;lt;ref&amp;gt;[https://holstebro-htx.dk/index.php/Word_Kildeliste Kildelister] anvendt i Microsoft Word&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Normal Internet-kilde til kode===&lt;br /&gt;
I dette eksempel er der angivet hvordan man ville dokumentere at man har anvendt kode fra et bibliotek til noget hardware på en [[Arduino]]. I det tænkte eksempel er det en 4 kanals AD-konverter&amp;lt;ref&amp;gt;[https://arduinotech.dk/shop/ads1115-module-4-channel-16-bit-i2c-adc-with-pro-gain-amplifier 4 kanals AD-konverter] fra ArduinoTech&amp;lt;/ref&amp;gt;, der er købt som modul.&lt;br /&gt;
&lt;br /&gt;
For at kunne anvende modulet i koden skal der kommunikeres med modulet på en måde, som er angivet i beskrivelsen af modulet - det er dog ikke nødvendigt at sætte sig ind i den grundlæggende kommunikation, hvis man blot ønsker at få værdier ind i sin software. Som en dokumentation for hvordan man anvender biblioteket kan man skrive følgende:&lt;br /&gt;
&lt;br /&gt;
====Eksempel på dokumentation====&lt;br /&gt;
Til at hente værdierne fra den 4 kanals AD-konverter anvendes et bibliotek fundet på GitHub (Singh, 2018) som kan indlæse de analoge spændinger.&lt;br /&gt;
Til at sætte AD-konverteren rigtigt op, til at kunne læse 4 spændinger, så anvendes eksemplet ”ADS1115_SingleEnded.ino” og i setup skrives følgende kode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
    ads.getAddr_ADS1115(ADS1115_DEFAULT_ADDRESS);   // 0x48, 1001 000 (ADDR = GND)&lt;br /&gt;
    ads.setGain(GAIN_TWO);          // 2x gain   +/- 2.048V  1 bit = 0.0625mV (default)&lt;br /&gt;
    ads.setMode(MODE_CONTIN);       // Continuous conversion mode&lt;br /&gt;
    ads.setRate(RATE_128);          // 128SPS (default)&lt;br /&gt;
    ads.setOSMode(OSMODE_SINGLE);   // Set to start a single-conversion&lt;br /&gt;
    ads.begin();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
I [[loop()]] testes i første omgang, om det kan lade sig gøre at læse de 4 kanaler. Dette gøres ved at afvikle følgende testkode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
    address = ads.ads_i2cAddress;&lt;br /&gt;
    Wire.beginTransmission(address);&lt;br /&gt;
    error = Wire.endTransmission();&lt;br /&gt;
    if (error == 0)&lt;br /&gt;
    {&lt;br /&gt;
        int16_t adc0, adc1, adc2, adc3;&lt;br /&gt;
&lt;br /&gt;
        adc0 = ads.Measure_SingleEnded(0);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 1: &amp;quot;);&lt;br /&gt;
        Serial.println(adc0);&lt;br /&gt;
        adc1 = ads.Measure_SingleEnded(1);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 2: &amp;quot;);&lt;br /&gt;
        Serial.println(adc1);&lt;br /&gt;
        adc2 = ads.Measure_SingleEnded(2);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 3: &amp;quot;);&lt;br /&gt;
        Serial.println(adc2);&lt;br /&gt;
        adc3 = ads.Measure_SingleEnded(3);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 4: &amp;quot;);&lt;br /&gt;
        Serial.println(adc3);&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Denne test giver det ønskede resultat.&lt;br /&gt;
&lt;br /&gt;
Ud fra denne beskrivelse viser man, at man tager andres kode, og anvender ind i sit eget projekt, og man angiver præcist i sin beskrivelse hvad man har taget fra andres kode.&lt;br /&gt;
&lt;br /&gt;
I kildelisten vil kilden optræde på følgende måde:&lt;br /&gt;
&lt;br /&gt;
Singh, Y., 2018. Arduino Library ADS1115 16 bit 4 channel ADC. [Online] &amp;lt;br /&amp;gt;&lt;br /&gt;
Available at: https://github.com/ncdcommunity/Arduino_Library_ADS1115_16Bit_4Channel_ADC&amp;lt;br /&amp;gt;&lt;br /&gt;
[Senest hentet eller vist den 15 marts 2024].&lt;br /&gt;
&lt;br /&gt;
===ChatGPT som kilde til kode===&lt;br /&gt;
Det følgende er skrevet med udgangspunkt i det der er beskrevet på viden.ai&amp;lt;ref&amp;gt;[https://viden.ai/korrekt-kildehenvisning-af-chatgpt/ Korrekt kildehenvisning af ChatGPT]&amp;lt;/ref&amp;gt;. hvor der angives hvordan man kildehenviser, men også lidt om hvordan man håndterer det i tekst - i korte træk, lav et metodeafsnit, beskriv hvad man gør og vær meget redelig, ved at man angiver hvad man har fået af ChatGPT ved at lægge det ved som et bilag.&lt;br /&gt;
&lt;br /&gt;
Hvis man forstår at prompte fornuftigt, så er ChatGPT faktisk ret god til at foreslå kode, der kan anvendes, men ligesom det er plagiat hvis man kopierer fra nettet, så er det plagiat, hvis man lader ChatGPT skrive store dele af ens program for sig.&lt;br /&gt;
&lt;br /&gt;
Som det er formuleret i vejledningen til både programmering C og B, så kan man anvende ChatGPT til hjælp i fejlfinding af kode. For at kunne kildehenvise korrekt til hjælp med fejlfinding, så skal man angive hvad man har promptet til ChatGPT og hvad den har svaret - det kan placeres i bilag.&lt;br /&gt;
&lt;br /&gt;
En anden ting, som også er OK at få hjælp med er, at komme i gang med programmet - det er denne problematik der her gives et eksempel på. I eksemplet beskrives hvad man skal skrive i sin dokumentation, når man har anvendt denne hjælp, og der er forslag til hvordan man kommer videre i projektet.&lt;br /&gt;
&lt;br /&gt;
Konkret er det starten på udviklingen af et lille spil med bolde i et vindue, udviklet i Processing, der tages udgangspunkt i.&lt;br /&gt;
&lt;br /&gt;
====Metodeafsnit med omtale af ChatGPT====&lt;br /&gt;
Når man anvender CharGPT, så skal man dokumentere hvordan man har gjort det, og hvilke overvejelser der ligger bag det. Det betegnes i rapportskrivning som et metodeafsnit. Det kunne i dette eksempel lyde:&lt;br /&gt;
&lt;br /&gt;
For at få en fornuftig start på programkoden er der brugt ChatGPT til at få rammerne på koden etableret, og til at få et system, så der kan optræde flere bolde i programvinduet. Det er ChatGPT 3.5 (OpenAI, 2023)&amp;lt;ref&amp;gt;[https://chat.openai.com/chat Indgangen til ChatGPT 3.5]&amp;lt;/ref&amp;gt; der er anvendt til denne hjælp. Til programstarten blev der promptet efter at få et programvindue på 800x600 hvor en bold bevæger sig rundt. Den foreslåede kode blev kopieret ind i processings IDE (Processing, 2024)&amp;lt;ref&amp;gt;[https://processing.org Hovedsiden for Processing]&amp;lt;/ref&amp;gt; og testet – den opførte sig som forventet.&lt;br /&gt;
&lt;br /&gt;
Derefter blev der promptet efter at få den bold der bevægede sig til at dele sig op i to, når man klikker på den med musen. Dette resulterede i en væsentligt anderledes kode, som igen blev kopieret ind i processing og testet, og igen med et acceptabelt resultat. Dialogen med ChatGPT (OpenAI, 2023) og herunder de to koder, kan ses i bilag 1.&lt;br /&gt;
&lt;br /&gt;
Herefter er resten af koden udviklet på traditionel vis, hvor første trin var at dokumentere princippet i den foreslåede kode, specielt den Ball klasse der blev introduceret for at kunne arbejde med flere bolde i vinduet.&lt;br /&gt;
&lt;br /&gt;
Det nævnte bilag 1 [[media:ChatGPT-dialog-1.pdf|kan ses i denne PDF]].&lt;br /&gt;
&lt;br /&gt;
====Dokumentation af koden udviklet af ChatGPT====&lt;br /&gt;
Da der skulle kunne dannes nye bolde så oprettes der en klasse, som ChatGPT skriver det i dialogen i Bilag 1:&lt;br /&gt;
&lt;br /&gt;
: &#039;&#039;&amp;quot;Dette kodeeksempel opretter en klasse kaldet Ball, som repræsenterer boldobjekterne. Når musen klikkes, kontrolleres det, om musens position er inden for en bold. Hvis det er tilfældet, oprettes to nye boldobjekter, der bevæger sig i forskellige retninger, og den originale bold fjernes fra arrayet.&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Ved at teste koden kan man se at det ikke er det helt rigtige den formulerer - der oprettes godt nok to nye bold-objekter, men det er ikke den oprindelige bold der fjernes, det er den ene af de ny-oprettede bolde. Det kan ses ved at de to bolde kommer i samme position, og den ene fortsætter i samme retning (den oprindelige), mens den ny-oprettede går i en tilfældig retning. Dette rettes til senere i dokumentationen under &amp;quot;oprettelse af ny bold&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
For at have en god struktur i koden, så placeres klassen Ball i en fil for sig kaldet Ball. Denne fil starter med at definere koden som en klasse med linjen:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
class Ball {&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dernæst defineres klassens egenskaber, der er boldens position og hastighed samt en fast diameter. Ud over det er der en x- og y-retning defineret. Den anvendes til at sige om bolden bevæger sig i en positiv eller negativ retning, så de skifter mellem +1 og -1, når kanterne rammes.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  float x, y;&lt;br /&gt;
  float xspeed, yspeed;&lt;br /&gt;
  int diameter = 30;&lt;br /&gt;
  int xdirection = 1;&lt;br /&gt;
  int ydirection = 1;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der defineres to forskellige constructors til bolden. Den første anvendes til at danne den første bold med, hvor position og hastighed sættes tilfældigt.&lt;br /&gt;
&lt;br /&gt;
Her forudses et problem at der kan komme et randfænomen, hvis bolden dannes, så den ligger med noget uden for skærmen. Da det er tilfældigt; så er det sjældent problemet opstår. For at fremprovokere det oftere er det testet med en diameter på 200, hvor det kunne ses at bolden bliver &amp;quot;hængende&amp;quot; i kanten.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  Ball() {&lt;br /&gt;
    x = random(width);&lt;br /&gt;
    y = random(height);&lt;br /&gt;
    xspeed = random(0.5, 2);&lt;br /&gt;
    yspeed = random(0.5, 2);&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Dette rettes ved at omskrive den foreslåede constructor til følgende kode, hvor bolden placeres mindst en halv diameter fra kanten:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  Ball() {&lt;br /&gt;
    x = random(diameter / 2, width - diameter / 2);&lt;br /&gt;
    y = random(diameter / 2, height - diameter / 2);&lt;br /&gt;
    xspeed = random(0.5, 2);&lt;br /&gt;
    yspeed = random(0.5, 2);&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Den anden constructor tager fire parametre, der er positionen og hastigheden. Denne constructor anvendes, når der skal dannes nye bolde, hvor koden netop skal starte den nye bold i den oprindelige bolds position, og med en ny retning.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  Ball(float x, float y, float xspeed, float yspeed) {&lt;br /&gt;
    this.x = x;&lt;br /&gt;
    this.y = y;&lt;br /&gt;
    this.xspeed = xspeed;&lt;br /&gt;
    this.yspeed = yspeed;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ud over disse standard ting til oprettelsen af objekter, så er der 3 metoder i klassen. Den første er en move() metode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  void move() {&lt;br /&gt;
    x = x + (xspeed * xdirection);&lt;br /&gt;
    y = y + (yspeed * ydirection);&lt;br /&gt;
&lt;br /&gt;
    if ((x + diameter/2 &amp;gt;= width) || (x - diameter/2 &amp;lt;= 0)) {&lt;br /&gt;
      xdirection *= -1;&lt;br /&gt;
    }&lt;br /&gt;
    if ((y + diameter/2 &amp;gt;= height) || (y - diameter/2 &amp;lt;= 0)) {&lt;br /&gt;
      ydirection *= -1;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Måden metoden virker på er at den lægger hastigheden til boldens position (både x og y), og hvis boldens position (både i x og y) er kommet uden for rammen, så ændres retningen for enten x eller y.&lt;br /&gt;
&lt;br /&gt;
For at kunne vise bolden er der en display() metode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  void display() {&lt;br /&gt;
    ellipse(x, y, diameter, diameter);&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Den sidste metode hedder contains(), og den tager en position som parameter til metoden. Der undersøges så om den position ligger inden for bolden ved at se om afstanden mellem boldens center og den testede position er mindre end den halve diameter. Hvis den er inden for bolden, så returneres true, ellers returneres false:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  boolean contains(float x, float y) {&lt;br /&gt;
    float d = dist(x, y, this.x, this.y);&lt;br /&gt;
    if (d &amp;lt; diameter/2) {&lt;br /&gt;
      return true;&lt;br /&gt;
    } else {&lt;br /&gt;
      return false;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Oprettelse af ny bold====&lt;br /&gt;
I den oprindelige kode undersøges om der er klikket på en bold, ved at alle bolde løbes igennem i mousePressed() funktionen, og med metoden contains undersøges om der er klikket på en bold. Denne måde at undersøge alle bolde på beholdes.&lt;br /&gt;
&lt;br /&gt;
Som omtalt er det ikke den smarteste måde til at dele bolden op i to, der anvendes. Som det ses i koden herunder, så appendes der to nye bolde på med den oprindelige bolds x- og y-position på samt tilfældige x- og y-hastigheder. Disse to bolde lægges i slutningen af arrayet. Derefter anvendes shorten&amp;lt;ref&amp;gt;[https://processing.org/reference/shorten_.html Processings shorten metode til arrays]&amp;lt;/ref&amp;gt; til at fjerne et element, men da det element der fjernes er det sidste element i arrayet, så fjernes der bare den sidst oprettede bold.&lt;br /&gt;
&lt;br /&gt;
Hvis man var tilfreds med den opførsel, så kunne man blot fjerne kodelinjen med den anden append og kodelinjen med shorten. Så ville man have samme funktion.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
    if (balls[i].contains(mouseX, mouseY)) {&lt;br /&gt;
      balls = (Ball[]) append(balls, new Ball(balls[i].x, balls[i].y, random(-5, 5), random(-5, 5)));&lt;br /&gt;
      balls = (Ball[]) append(balls, new Ball(balls[i].x, balls[i].y, random(-5, 5), random(-5, 5)));&lt;br /&gt;
      balls = (Ball[]) shorten(balls);&lt;br /&gt;
      break;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Den nye bold der oprettes får bare en tilfældig retning, og den oprindelige bold fortsætter bare i den retning den var på vej i. Det er ikke den opførsel der ønskes i spillet. Der ønskes i stedet at det ser ud som om bolden &amp;quot;splittes op&amp;quot; i 2 bolde, og den opførsel laves ved at lade den oprindelige bold ændre 30 grader til den ene side, og den nye bold får 30 grader til den anden side.&lt;br /&gt;
&lt;br /&gt;
For at gøre dette, så oprettes der en metode multiply() i klassen Ball. Denne metode returnerer en ny bold af typen Ball, så nu kan koden i museklikket skrives som følger:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
    if (balls[i].contains(mouseX, mouseY)) {&lt;br /&gt;
      balls = (Ball[]) append(balls, balls[i].multiply());&lt;br /&gt;
      break;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Som det kan ses, så appendes der en ny bold ind i balls-arrayet, ud fra metoden multiply().&lt;br /&gt;
&lt;br /&gt;
Metoden multiply() oprettes inde i klassen med følgende kode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  Ball multiply() {&lt;br /&gt;
    xspeed *= xdirection;&lt;br /&gt;
    yspeed *= ydirection;&lt;br /&gt;
    xdirection = 1;&lt;br /&gt;
    ydirection = 1;&lt;br /&gt;
    float speed = dist(0, 0, xspeed, yspeed);&lt;br /&gt;
    float angle = acos(xspeed / speed);&lt;br /&gt;
    if (yspeed &amp;lt; 0) angle = 0.0 - angle;&lt;br /&gt;
    speed *= 1.5;&lt;br /&gt;
    xspeed = speed * cos(angle + PI / 6);&lt;br /&gt;
    yspeed = speed * sin(angle + PI / 6);&lt;br /&gt;
    Ball b = new Ball(x, y, speed * cos(angle - PI / 6), speed * sin(angle - PI / 6));&lt;br /&gt;
    return b;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Først regnes retningen over i xspeed og yspeed, så de kan være både positive og negative. På den måde indeholder de to variabler retningen.&lt;br /&gt;
&lt;br /&gt;
Dernæst omregnes x- og y-hastigheden til en samlet hastighed speed og en vinkel angle, som kan være mellem +PI og -PI (+/- 180 grader).&lt;br /&gt;
&lt;br /&gt;
Begge bolde skal bevæge sig hurtigere efter de er delt, så spillet gradvist bliver sværere, derfor ganges hastigheden med 1,5.&lt;br /&gt;
&lt;br /&gt;
Den oprindelige bold får nu en ny retning, ved at udregne x- og y-hastigheden ud fra den nye hastighed og vinklen plus 30 grader.&lt;br /&gt;
&lt;br /&gt;
Til sidst oprettes en ny bold med samme position som den oprindelige og en x- og y-hastighed udregnet fra den oprindelige bolds hastighed og vinklen minus 30 grader. Denne bold returneres fra metoden.&lt;br /&gt;
&lt;br /&gt;
==Refleksioner over anvendelsen==&lt;br /&gt;
Der er selvfølgelig stadig lang vej til man har et færdigt spil, men ideen var også at tage fat i, hvordan man anvender ChatGPT på en ordentlig redelig måde i et programmeringsprojekt. Dette kan selvfølgelig altid gradbøjes, men hvis man håndterer anvendelsen som vist i eksemplet, så vil man ikke gøre noget der kommer i nærheden af plagiat.&lt;br /&gt;
==Referencer== &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt; &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Programmering}}&lt;br /&gt;
&lt;br /&gt;
[[Kategori:Programmering teknik]]&lt;/div&gt;</summary>
		<author><name>Bar</name></author>
	</entry>
	<entry>
		<id>https://www.htxarduino.dk/index.php?title=Programmering_med_ChatGPT&amp;diff=5398</id>
		<title>Programmering med ChatGPT</title>
		<link rel="alternate" type="text/html" href="https://www.htxarduino.dk/index.php?title=Programmering_med_ChatGPT&amp;diff=5398"/>
		<updated>2024-03-17T08:27:38Z</updated>

		<summary type="html">&lt;p&gt;Bar: /* Dokumentation af koden udviklet af ChatGPT */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Det er ikke så svært at få ChatGPT&amp;lt;ref&amp;gt;[https://chat.openai.com/auth/login ChatGPT Login] - Indgangen til ChatGPT&amp;lt;/ref&amp;gt; til at lave kode, der skal man blot beskrive hvad man gerne vil have programmet til at gøre, og så kopiere den kode, der kommer ud af det - det giver tit ret gode resultater.&lt;br /&gt;
&lt;br /&gt;
Problemet med at anvende ChatGPT i forbindelse med skoleprojekter er, at man skal have forståelsen med i det, og at man ikke kan blive anklaget for plagiat.&lt;br /&gt;
&lt;br /&gt;
==Hvad må man ikke i en skoleprojekt==&lt;br /&gt;
*Man må ikke kopiere kode, som man ikke selv har skrevet, til et programmeringsprodukt uden at man angiver en kilde. Det er uanset hvor koden stammer fra, også selvom man har brugt ChatGPT til at &amp;quot;udvikle&amp;quot; koden.&lt;br /&gt;
*Man må ikke aflevere et produkt hvor de primære dele af koden er kopieret, heller ikke selvom man kildehenviser.&lt;br /&gt;
*Man må ikke få ChatGPT til at dokumentere sin kode, ved at man kopierer ChatGPT&#039;s beskrivelse ind i sin dokumentation af koden.&lt;br /&gt;
&lt;br /&gt;
De beskrevne eksempler er at betragte som plagiat, og vil blive håndteret efter skolens ordensregler, hvilket i værste fald kan ende med at et fag annulleres eller man bliver bortvist fra uddannelsen.&lt;br /&gt;
==Hvad er tilladt med ChatGPT==&lt;br /&gt;
På samme måde som man må anvende kilder fra internettet, så må man i programmerings-faget i gymnasiet anvende ChatGPT i udviklingen af kode til et programmeringsprodukt. Dette er blevet tilladt via en revidering af vejledningen til faget&amp;lt;ref&amp;gt;[https://www.uvm.dk/-/media/filer/uvm/udd/gym/pdf23/aug/vejledninger/valgfag/230807-programmering-c--valgfag.pdf Vejledning] til Valgfaget Programmering C&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
I vejledningen står der som følger:&lt;br /&gt;
&lt;br /&gt;
: &#039;&#039;&amp;quot;brug af internettet er tilladt som fagligt hjælpemiddel ved de mundtlige prøver, inkluderer de tilladte hjælpemidler anvendelsen af chatbots og lignende på en måde, som afspejler, hvordan man arbejder i den daglige undervisning. Dette kunne fx være brug af ChatGPT til at debugge kode.&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Det skal altså afspejle den normale brug, som man også har ved at bruge internettet. Som angivet under hvad man ikke må, så er den normale brug, at man anvender information til at lære et programmere, men at man ikke tager så meget af sit produkt fra nettet, så man ikke har en forståelse af hvordan produktet er sammensat.&lt;br /&gt;
&lt;br /&gt;
Videre i vejledningen står der:&lt;br /&gt;
&lt;br /&gt;
: &#039;&#039;&amp;quot;I forhold til denne type hjælpemidler er det vigtigt at være opmærksom på, at den tilladte anvendelse er betinget af, at hjælpemidlerne kun benyttes i et omfang, hvor prøvebesvarelsen er selvstændig og udelukkende elevens egen.&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Igen understreges at det der afleveres skal være elevens selvstændigt udviklede produkt og dokumentation, hvor man på normal vis anvender internettet som et værktøj til at bibringe forståelse.&lt;br /&gt;
&lt;br /&gt;
==Problemet med ChatGPT==&lt;br /&gt;
Ligesom man ikke kan kilde-henvise til &amp;quot;google&amp;quot;, for at angive at man har fundet informationer på nettet, så kan man heller ikke kildehenvise til ChatGPT direkte som en kilde.&lt;br /&gt;
&lt;br /&gt;
Når man finder informationer med google&#039;, så skal man angive hvor på nettet man har fundet dem med så præcis en kildehenvisning, at man kan se den information der er blevet anvendt.&lt;br /&gt;
&lt;br /&gt;
Denne type henvisning kan man ikke lave i forhold til ChatGPT, da sprogmodellen der ligger bag ChatGPT konstant udvikler sig, samt at de svar sprogmodellen giver har et randomiseret element indbygget, som er med til at give bedre svar&amp;lt;ref&amp;gt;[https://www.it-vest.dk/arrangementer/sig-webinar-14-marts-2024-kunstig-intelligens-og-chatgpt-hvordan-virker-det-og-skal-vi-bare-opgive-undervisning-og-eksamen Webinar om kunstig intelligens]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Her er man altså nødt til at tage andre metoder i brug, for at kunne dokumentere at man har udviklet sit produkt ordentligt og redeligt.&lt;br /&gt;
&lt;br /&gt;
==Kildehenvisninger i dokumentation==&lt;br /&gt;
Der kan være forskellige standarder for hvordan man kildehenviser i forskellige uddannelser, dette er skrevet med udgangspunkt i at man anvender Word bibliografi-værktøj og her vist med en Harvard-lignende standard&amp;lt;ref&amp;gt;[https://holstebro-htx.dk/index.php/Word_Kildeliste Kildelister] anvendt i Microsoft Word&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Normal Internet-kilde til kode===&lt;br /&gt;
I dette eksempel er der angivet hvordan man ville dokumentere at man har anvendt kode fra et bibliotek til noget hardware på en [[Arduino]]. I det tænkte eksempel er det en 4 kanals AD-konverter&amp;lt;ref&amp;gt;[https://arduinotech.dk/shop/ads1115-module-4-channel-16-bit-i2c-adc-with-pro-gain-amplifier 4 kanals AD-konverter] fra ArduinoTech&amp;lt;/ref&amp;gt;, der er købt som modul.&lt;br /&gt;
&lt;br /&gt;
For at kunne anvende modulet i koden skal der kommunikeres med modulet på en måde, som er angivet i beskrivelsen af modulet - det er dog ikke nødvendigt at sætte sig ind i den grundlæggende kommunikation, hvis man blot ønsker at få værdier ind i sin software. Som en dokumentation for hvordan man anvender biblioteket kan man skrive følgende:&lt;br /&gt;
&lt;br /&gt;
====Eksempel på dokumentation====&lt;br /&gt;
Til at hente værdierne fra den 4 kanals AD-konverter anvendes et bibliotek fundet på GitHub (Singh, 2018) som kan indlæse de analoge spændinger.&lt;br /&gt;
Til at sætte AD-konverteren rigtigt op, til at kunne læse 4 spændinger, så anvendes eksemplet ”ADS1115_SingleEnded.ino” og i setup skrives følgende kode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
    ads.getAddr_ADS1115(ADS1115_DEFAULT_ADDRESS);   // 0x48, 1001 000 (ADDR = GND)&lt;br /&gt;
    ads.setGain(GAIN_TWO);          // 2x gain   +/- 2.048V  1 bit = 0.0625mV (default)&lt;br /&gt;
    ads.setMode(MODE_CONTIN);       // Continuous conversion mode&lt;br /&gt;
    ads.setRate(RATE_128);          // 128SPS (default)&lt;br /&gt;
    ads.setOSMode(OSMODE_SINGLE);   // Set to start a single-conversion&lt;br /&gt;
    ads.begin();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
I [[loop()]] testes i første omgang, om det kan lade sig gøre at læse de 4 kanaler. Dette gøres ved at afvikle følgende testkode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
    address = ads.ads_i2cAddress;&lt;br /&gt;
    Wire.beginTransmission(address);&lt;br /&gt;
    error = Wire.endTransmission();&lt;br /&gt;
    if (error == 0)&lt;br /&gt;
    {&lt;br /&gt;
        int16_t adc0, adc1, adc2, adc3;&lt;br /&gt;
&lt;br /&gt;
        adc0 = ads.Measure_SingleEnded(0);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 1: &amp;quot;);&lt;br /&gt;
        Serial.println(adc0);&lt;br /&gt;
        adc1 = ads.Measure_SingleEnded(1);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 2: &amp;quot;);&lt;br /&gt;
        Serial.println(adc1);&lt;br /&gt;
        adc2 = ads.Measure_SingleEnded(2);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 3: &amp;quot;);&lt;br /&gt;
        Serial.println(adc2);&lt;br /&gt;
        adc3 = ads.Measure_SingleEnded(3);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 4: &amp;quot;);&lt;br /&gt;
        Serial.println(adc3);&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Denne test giver det ønskede resultat.&lt;br /&gt;
&lt;br /&gt;
Ud fra denne beskrivelse viser man, at man tager andres kode, og anvender ind i sit eget projekt, og man angiver præcist i sin beskrivelse hvad man har taget fra andres kode.&lt;br /&gt;
&lt;br /&gt;
I kildelisten vil kilden optræde på følgende måde:&lt;br /&gt;
&lt;br /&gt;
Singh, Y., 2018. Arduino Library ADS1115 16 bit 4 channel ADC. [Online] &amp;lt;br /&amp;gt;&lt;br /&gt;
Available at: https://github.com/ncdcommunity/Arduino_Library_ADS1115_16Bit_4Channel_ADC&amp;lt;br /&amp;gt;&lt;br /&gt;
[Senest hentet eller vist den 15 marts 2024].&lt;br /&gt;
&lt;br /&gt;
===ChatGPT som kilde til kode===&lt;br /&gt;
Det følgende er skrevet med udgangspunkt i det der er beskrevet på viden.ai&amp;lt;ref&amp;gt;[https://viden.ai/korrekt-kildehenvisning-af-chatgpt/ Korrekt kildehenvisning af ChatGPT]&amp;lt;/ref&amp;gt;. hvor der angives hvordan man kildehenviser, men også lidt om hvordan man håndterer det i tekst - i korte træk, lav et metodeafsnit, beskriv hvad man gør og vær meget redelig, ved at man angiver hvad man har fået af ChatGPT ved at lægge det ved som et bilag.&lt;br /&gt;
&lt;br /&gt;
Hvis man forstår at prompte fornuftigt, så er ChatGPT faktisk ret god til at foreslå kode, der kan anvendes, men ligesom det er plagiat hvis man kopierer fra nettet, så er det plagiat, hvis man lader ChatGPT skrive store dele af ens program for sig.&lt;br /&gt;
&lt;br /&gt;
Som det er formuleret i vejledningen til både programmering C og B, så kan man anvende ChatGPT til hjælp i fejlfinding af kode. For at kunne kildehenvise korrekt til hjælp med fejlfinding, så skal man angive hvad man har promptet til ChatGPT og hvad den har svaret - det kan placeres i bilag.&lt;br /&gt;
&lt;br /&gt;
En anden ting, som også er OK at få hjælp med er, at komme i gang med programmet - det er denne problematik der her gives et eksempel på. I eksemplet beskrives hvad man skal skrive i sin dokumentation, når man har anvendt denne hjælp, og der er forslag til hvordan man kommer videre i projektet.&lt;br /&gt;
&lt;br /&gt;
Konkret er det starten på udviklingen af et lille spil med bolde i et vindue, udviklet i Processing, der tages udgangspunkt i.&lt;br /&gt;
&lt;br /&gt;
====Metodeafsnit med omtale af ChatGPT====&lt;br /&gt;
Når man anvender CharGPT, så skal man dokumentere hvordan man har gjort det, og hvilke overvejelser der ligger bag det. Det betegnes i rapportskrivning som et metodeafsnit. Det kunne i dette eksempel lyde:&lt;br /&gt;
&lt;br /&gt;
For at få en fornuftig start på programkoden er der brugt ChatGPT til at få rammerne på koden etableret, og til at få et system, så der kan optræde flere bolde i programvinduet. Det er ChatGPT 3.5 (OpenAI, 2023)&amp;lt;ref&amp;gt;[https://chat.openai.com/chat Indgangen til ChatGPT 3.5]&amp;lt;/ref&amp;gt; der er anvendt til denne hjælp. Til programstarten blev der promptet efter at få et programvindue på 800x600 hvor en bold bevæger sig rundt. Den foreslåede kode blev kopieret ind i processings IDE (Processing, 2024)&amp;lt;ref&amp;gt;[https://processing.org Hovedsiden for Processing]&amp;lt;/ref&amp;gt; og testet – den opførte sig som forventet.&lt;br /&gt;
&lt;br /&gt;
Derefter blev der promptet efter at få den bold der bevægede sig til at dele sig op i to, når man klikker på den med musen. Dette resulterede i en væsentligt anderledes kode, som igen blev kopieret ind i processing og testet, og igen med et acceptabelt resultat. Dialogen med ChatGPT (OpenAI, 2023) og herunder de to koder, kan ses i bilag 1.&lt;br /&gt;
&lt;br /&gt;
Herefter er resten af koden udviklet på traditionel vis, hvor første trin var at dokumentere princippet i den foreslåede kode, specielt den Ball klasse der blev introduceret for at kunne arbejde med flere bolde i vinduet.&lt;br /&gt;
&lt;br /&gt;
Det nævnte bilag 1 [[media:ChatGPT-dialog-1.pdf|kan ses i denne PDF]].&lt;br /&gt;
&lt;br /&gt;
====Dokumentation af koden udviklet af ChatGPT====&lt;br /&gt;
Da der skulle kunne dannes nye bolde så oprettes der en klasse, som ChatGPT skriver det i dialogen i Bilag 1:&lt;br /&gt;
&lt;br /&gt;
: &#039;&#039;&amp;quot;Dette kodeeksempel opretter en klasse kaldet Ball, som repræsenterer boldobjekterne. Når musen klikkes, kontrolleres det, om musens position er inden for en bold. Hvis det er tilfældet, oprettes to nye boldobjekter, der bevæger sig i forskellige retninger, og den originale bold fjernes fra arrayet.&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Ved at teste koden kan man se at det ikke er det helt rigtige den formulerer - der oprettes godt nok to nye bold-objekter, men det er ikke den oprindelige bold der fjernes, det er den ene af de ny-oprettede bolde. Det kan ses ved at de to bolde kommer i samme position, og den ene fortsætter i samme retning (den oprindelige), mens den ny-oprettede går i en tilfældig retning. Dette rettes til senere i dokumentationen under &amp;quot;oprettelse af ny bold&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
For at have en god struktur i koden, så placeres klassen Ball i en fil for sig kaldet Ball. Denne fil starter med at definere koden som en klasse med linjen:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
class Ball {&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dernæst defineres klassens egenskaber, der er boldens position og hastighed samt en fast diameter. Ud over det er der en x- og y-retning defineret. Den anvendes til at sige om bolden bevæger sig i en positiv eller negativ retning, så de skifter mellem +1 og -1, når kanterne rammes.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  float x, y;&lt;br /&gt;
  float xspeed, yspeed;&lt;br /&gt;
  int diameter = 30;&lt;br /&gt;
  int xdirection = 1;&lt;br /&gt;
  int ydirection = 1;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der defineres to forskellige constructors til bolden. Den første anvendes til at danne den første bold med, hvor position og hastighed sættes tilfældigt.&lt;br /&gt;
&lt;br /&gt;
Her forudses et problem at der kan komme et randfænomen, hvis bolden dannes, så den ligger med noget uden for skærmen. Da det er tilfældigt; så er det sjældent problemet opstår. For at fremprovokere det oftere er det testet med en diameter på 200, hvor det kunne ses at bolden bliver &amp;quot;hængende&amp;quot; i kanten.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  Ball() {&lt;br /&gt;
    x = random(width);&lt;br /&gt;
    y = random(height);&lt;br /&gt;
    xspeed = random(0.5, 2);&lt;br /&gt;
    yspeed = random(0.5, 2);&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Dette rettes ved at omskrive den foreslåede constructor til følgende kode, hvor bolden placeres mindst en halv diameter fra kanten:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  Ball() {&lt;br /&gt;
    x = random(diameter / 2, width - diameter / 2);&lt;br /&gt;
    y = random(diameter / 2, height - diameter / 2);&lt;br /&gt;
    xspeed = random(0.5, 2);&lt;br /&gt;
    yspeed = random(0.5, 2);&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Den anden constructor tager fire parametre, der er positionen og hastigheden. Denne constructor anvendes, når der skal dannes nye bolde, hvor koden netop skal starte den nye bold i den oprindelige bolds position, og med en ny retning.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  Ball(float x, float y, float xspeed, float yspeed) {&lt;br /&gt;
    this.x = x;&lt;br /&gt;
    this.y = y;&lt;br /&gt;
    this.xspeed = xspeed;&lt;br /&gt;
    this.yspeed = yspeed;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ud over disse standard ting til oprettelsen af objekter, så er der 3 metoder i klassen. Den første er en move() metode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  void move() {&lt;br /&gt;
    x = x + (xspeed * xdirection);&lt;br /&gt;
    y = y + (yspeed * ydirection);&lt;br /&gt;
&lt;br /&gt;
    if ((x + diameter/2 &amp;gt;= width) || (x - diameter/2 &amp;lt;= 0)) {&lt;br /&gt;
      xdirection *= -1;&lt;br /&gt;
    }&lt;br /&gt;
    if ((y + diameter/2 &amp;gt;= height) || (y - diameter/2 &amp;lt;= 0)) {&lt;br /&gt;
      ydirection *= -1;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Måden metoden virker på er at den lægger hastigheden til boldens position (både x og y), og hvis boldens position (både i x og y) er kommet uden for rammen, så ændres retningen for enten x eller y.&lt;br /&gt;
&lt;br /&gt;
For at kunne vise bolden er der en display() metode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  void display() {&lt;br /&gt;
    ellipse(x, y, diameter, diameter);&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Den sidste metode hedder contains(), og den tager en position som parameter til metoden. Der undersøges så om den position ligger inden for bolden ved at se om afstanden mellem boldens center og den testede position er mindre end den halve diameter. Hvis den er inden for bolden, så returneres true, ellers returneres false:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  boolean contains(float x, float y) {&lt;br /&gt;
    float d = dist(x, y, this.x, this.y);&lt;br /&gt;
    if (d &amp;lt; diameter/2) {&lt;br /&gt;
      return true;&lt;br /&gt;
    } else {&lt;br /&gt;
      return false;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Oprettelse af ny bold====&lt;br /&gt;
I den oprindelige kode undersøges om der er klikket på en bold, ved at alle bolde løbes igennem i mousePressed() funktionen, og med metoden contains undersøges om der er klikket på en bold. Denne måde at undersøge alle bolde på beholdes.&lt;br /&gt;
&lt;br /&gt;
Som omtalt er det ikke den smarteste måde til at dele bolden op i to, der anvendes. Som det ses i koden herunder, så appendes der to nye bolde på med den oprindelige bolds x- og y-position på samt tilfældige x- og y-hastigheder. Disse to bolde lægges i slutningen af arrayet. Derefter anvendes shorten&amp;lt;ref&amp;gt;[https://processing.org/reference/shorten_.html Processings shorten metode til arrays]&amp;lt;/ref&amp;gt; til at fjerne et element, men da det element der fjernes er det sidste element i arrayet, så fjernes der bare den sidst oprettede bold.&lt;br /&gt;
&lt;br /&gt;
Hvis man var tilfreds med den opførsel, så kunne man blot fjerne kodelinjen med den anden append og kodelinjen med shorten. Så ville man have samme funktion.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
    if (balls[i].contains(mouseX, mouseY)) {&lt;br /&gt;
      balls = (Ball[]) append(balls, new Ball(balls[i].x, balls[i].y, random(-5, 5), random(-5, 5)));&lt;br /&gt;
      balls = (Ball[]) append(balls, new Ball(balls[i].x, balls[i].y, random(-5, 5), random(-5, 5)));&lt;br /&gt;
      balls = (Ball[]) shorten(balls);&lt;br /&gt;
      break;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Den nye bold der oprettes får bare en tilfældig retning, og den oprindelige bold fortsætter bare i den retning den var på vej i. Det er ikke den opførsel der ønskes i spillet. Der ønskes i stedet at det ser ud som om bolden &amp;quot;splittes op&amp;quot; i 2 bolde, og den opførsel laves ved at lade den oprindelige bold ændre 30 grader til den ene side, og den nye bold får 30 grader til den anden side.&lt;br /&gt;
&lt;br /&gt;
For at gøre dette, så oprettes der en metode multiply() i klassen Ball. Denne metode returnerer en ny bold af typen Ball, så nu kan koden i museklikket skrives som følger:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
    if (balls[i].contains(mouseX, mouseY)) {&lt;br /&gt;
      balls = (Ball[]) append(balls, balls[i].multiply());&lt;br /&gt;
      break;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Som det kan ses, så appendes der en ny bold ind i balls-arrayet, ud fra metoden multiply().&lt;br /&gt;
&lt;br /&gt;
Metoden multiply() oprettes inde i klassen med følgende kode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  Ball multiply() {&lt;br /&gt;
    xspeed *= xdirection;&lt;br /&gt;
    yspeed *= ydirection;&lt;br /&gt;
    xdirection = 1;&lt;br /&gt;
    ydirection = 1;&lt;br /&gt;
    float speed = dist(0, 0, xspeed, yspeed);&lt;br /&gt;
    float angle = acos(xspeed / speed);&lt;br /&gt;
    if (yspeed &amp;lt; 0) angle = 0.0 - angle;&lt;br /&gt;
    speed *= 1.5;&lt;br /&gt;
    xspeed = speed * cos(angle + PI / 6);&lt;br /&gt;
    yspeed = speed * sin(angle + PI / 6);&lt;br /&gt;
    Ball b = new Ball(x, y, speed * cos(angle - PI / 6), speed * sin(angle - PI / 6));&lt;br /&gt;
    return b;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Først regnes retningen over i xspeed og yspeed, så de kan være både positive og negative. På den måde indeholder de to variabler retningen.&lt;br /&gt;
&lt;br /&gt;
Dernæst omregnes x- og y-hastigheden til en samlet hastighed speed og en vinkel angle, som kan være mellem +PI og -PI (+/- 180 grader).&lt;br /&gt;
&lt;br /&gt;
Begge bolde skal bevæge sig hurtigere efter de er delt, så spillet gradvist bliver sværere, derfor ganges hastigheden med 1,5.&lt;br /&gt;
&lt;br /&gt;
Den oprindelige bold får nu en ny retning, ved at udregne x- og y-hastigheden ud fra den nye hastighed og vinklen plus 30 grader.&lt;br /&gt;
&lt;br /&gt;
Til sidst oprettes en ny bold med samme position som den oprindelige og en x- og y-hastighed udregnet fra den oprindelige bolds hastighed og vinklen minus 30 grader. Denne bold returneres fra metoden.&lt;br /&gt;
&lt;br /&gt;
==Referencer== &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt; &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Programmering}}&lt;br /&gt;
&lt;br /&gt;
[[Kategori:Programmering teknik]]&lt;/div&gt;</summary>
		<author><name>Bar</name></author>
	</entry>
	<entry>
		<id>https://www.htxarduino.dk/index.php?title=Programmering_med_ChatGPT&amp;diff=5397</id>
		<title>Programmering med ChatGPT</title>
		<link rel="alternate" type="text/html" href="https://www.htxarduino.dk/index.php?title=Programmering_med_ChatGPT&amp;diff=5397"/>
		<updated>2024-03-17T08:22:43Z</updated>

		<summary type="html">&lt;p&gt;Bar: /* Metodeafsnit med omtale af ChatGPT */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Det er ikke så svært at få ChatGPT&amp;lt;ref&amp;gt;[https://chat.openai.com/auth/login ChatGPT Login] - Indgangen til ChatGPT&amp;lt;/ref&amp;gt; til at lave kode, der skal man blot beskrive hvad man gerne vil have programmet til at gøre, og så kopiere den kode, der kommer ud af det - det giver tit ret gode resultater.&lt;br /&gt;
&lt;br /&gt;
Problemet med at anvende ChatGPT i forbindelse med skoleprojekter er, at man skal have forståelsen med i det, og at man ikke kan blive anklaget for plagiat.&lt;br /&gt;
&lt;br /&gt;
==Hvad må man ikke i en skoleprojekt==&lt;br /&gt;
*Man må ikke kopiere kode, som man ikke selv har skrevet, til et programmeringsprodukt uden at man angiver en kilde. Det er uanset hvor koden stammer fra, også selvom man har brugt ChatGPT til at &amp;quot;udvikle&amp;quot; koden.&lt;br /&gt;
*Man må ikke aflevere et produkt hvor de primære dele af koden er kopieret, heller ikke selvom man kildehenviser.&lt;br /&gt;
*Man må ikke få ChatGPT til at dokumentere sin kode, ved at man kopierer ChatGPT&#039;s beskrivelse ind i sin dokumentation af koden.&lt;br /&gt;
&lt;br /&gt;
De beskrevne eksempler er at betragte som plagiat, og vil blive håndteret efter skolens ordensregler, hvilket i værste fald kan ende med at et fag annulleres eller man bliver bortvist fra uddannelsen.&lt;br /&gt;
==Hvad er tilladt med ChatGPT==&lt;br /&gt;
På samme måde som man må anvende kilder fra internettet, så må man i programmerings-faget i gymnasiet anvende ChatGPT i udviklingen af kode til et programmeringsprodukt. Dette er blevet tilladt via en revidering af vejledningen til faget&amp;lt;ref&amp;gt;[https://www.uvm.dk/-/media/filer/uvm/udd/gym/pdf23/aug/vejledninger/valgfag/230807-programmering-c--valgfag.pdf Vejledning] til Valgfaget Programmering C&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
I vejledningen står der som følger:&lt;br /&gt;
&lt;br /&gt;
: &#039;&#039;&amp;quot;brug af internettet er tilladt som fagligt hjælpemiddel ved de mundtlige prøver, inkluderer de tilladte hjælpemidler anvendelsen af chatbots og lignende på en måde, som afspejler, hvordan man arbejder i den daglige undervisning. Dette kunne fx være brug af ChatGPT til at debugge kode.&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Det skal altså afspejle den normale brug, som man også har ved at bruge internettet. Som angivet under hvad man ikke må, så er den normale brug, at man anvender information til at lære et programmere, men at man ikke tager så meget af sit produkt fra nettet, så man ikke har en forståelse af hvordan produktet er sammensat.&lt;br /&gt;
&lt;br /&gt;
Videre i vejledningen står der:&lt;br /&gt;
&lt;br /&gt;
: &#039;&#039;&amp;quot;I forhold til denne type hjælpemidler er det vigtigt at være opmærksom på, at den tilladte anvendelse er betinget af, at hjælpemidlerne kun benyttes i et omfang, hvor prøvebesvarelsen er selvstændig og udelukkende elevens egen.&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Igen understreges at det der afleveres skal være elevens selvstændigt udviklede produkt og dokumentation, hvor man på normal vis anvender internettet som et værktøj til at bibringe forståelse.&lt;br /&gt;
&lt;br /&gt;
==Problemet med ChatGPT==&lt;br /&gt;
Ligesom man ikke kan kilde-henvise til &amp;quot;google&amp;quot;, for at angive at man har fundet informationer på nettet, så kan man heller ikke kildehenvise til ChatGPT direkte som en kilde.&lt;br /&gt;
&lt;br /&gt;
Når man finder informationer med google&#039;, så skal man angive hvor på nettet man har fundet dem med så præcis en kildehenvisning, at man kan se den information der er blevet anvendt.&lt;br /&gt;
&lt;br /&gt;
Denne type henvisning kan man ikke lave i forhold til ChatGPT, da sprogmodellen der ligger bag ChatGPT konstant udvikler sig, samt at de svar sprogmodellen giver har et randomiseret element indbygget, som er med til at give bedre svar&amp;lt;ref&amp;gt;[https://www.it-vest.dk/arrangementer/sig-webinar-14-marts-2024-kunstig-intelligens-og-chatgpt-hvordan-virker-det-og-skal-vi-bare-opgive-undervisning-og-eksamen Webinar om kunstig intelligens]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Her er man altså nødt til at tage andre metoder i brug, for at kunne dokumentere at man har udviklet sit produkt ordentligt og redeligt.&lt;br /&gt;
&lt;br /&gt;
==Kildehenvisninger i dokumentation==&lt;br /&gt;
Der kan være forskellige standarder for hvordan man kildehenviser i forskellige uddannelser, dette er skrevet med udgangspunkt i at man anvender Word bibliografi-værktøj og her vist med en Harvard-lignende standard&amp;lt;ref&amp;gt;[https://holstebro-htx.dk/index.php/Word_Kildeliste Kildelister] anvendt i Microsoft Word&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Normal Internet-kilde til kode===&lt;br /&gt;
I dette eksempel er der angivet hvordan man ville dokumentere at man har anvendt kode fra et bibliotek til noget hardware på en [[Arduino]]. I det tænkte eksempel er det en 4 kanals AD-konverter&amp;lt;ref&amp;gt;[https://arduinotech.dk/shop/ads1115-module-4-channel-16-bit-i2c-adc-with-pro-gain-amplifier 4 kanals AD-konverter] fra ArduinoTech&amp;lt;/ref&amp;gt;, der er købt som modul.&lt;br /&gt;
&lt;br /&gt;
For at kunne anvende modulet i koden skal der kommunikeres med modulet på en måde, som er angivet i beskrivelsen af modulet - det er dog ikke nødvendigt at sætte sig ind i den grundlæggende kommunikation, hvis man blot ønsker at få værdier ind i sin software. Som en dokumentation for hvordan man anvender biblioteket kan man skrive følgende:&lt;br /&gt;
&lt;br /&gt;
====Eksempel på dokumentation====&lt;br /&gt;
Til at hente værdierne fra den 4 kanals AD-konverter anvendes et bibliotek fundet på GitHub (Singh, 2018) som kan indlæse de analoge spændinger.&lt;br /&gt;
Til at sætte AD-konverteren rigtigt op, til at kunne læse 4 spændinger, så anvendes eksemplet ”ADS1115_SingleEnded.ino” og i setup skrives følgende kode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
    ads.getAddr_ADS1115(ADS1115_DEFAULT_ADDRESS);   // 0x48, 1001 000 (ADDR = GND)&lt;br /&gt;
    ads.setGain(GAIN_TWO);          // 2x gain   +/- 2.048V  1 bit = 0.0625mV (default)&lt;br /&gt;
    ads.setMode(MODE_CONTIN);       // Continuous conversion mode&lt;br /&gt;
    ads.setRate(RATE_128);          // 128SPS (default)&lt;br /&gt;
    ads.setOSMode(OSMODE_SINGLE);   // Set to start a single-conversion&lt;br /&gt;
    ads.begin();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
I [[loop()]] testes i første omgang, om det kan lade sig gøre at læse de 4 kanaler. Dette gøres ved at afvikle følgende testkode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
    address = ads.ads_i2cAddress;&lt;br /&gt;
    Wire.beginTransmission(address);&lt;br /&gt;
    error = Wire.endTransmission();&lt;br /&gt;
    if (error == 0)&lt;br /&gt;
    {&lt;br /&gt;
        int16_t adc0, adc1, adc2, adc3;&lt;br /&gt;
&lt;br /&gt;
        adc0 = ads.Measure_SingleEnded(0);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 1: &amp;quot;);&lt;br /&gt;
        Serial.println(adc0);&lt;br /&gt;
        adc1 = ads.Measure_SingleEnded(1);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 2: &amp;quot;);&lt;br /&gt;
        Serial.println(adc1);&lt;br /&gt;
        adc2 = ads.Measure_SingleEnded(2);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 3: &amp;quot;);&lt;br /&gt;
        Serial.println(adc2);&lt;br /&gt;
        adc3 = ads.Measure_SingleEnded(3);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 4: &amp;quot;);&lt;br /&gt;
        Serial.println(adc3);&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Denne test giver det ønskede resultat.&lt;br /&gt;
&lt;br /&gt;
Ud fra denne beskrivelse viser man, at man tager andres kode, og anvender ind i sit eget projekt, og man angiver præcist i sin beskrivelse hvad man har taget fra andres kode.&lt;br /&gt;
&lt;br /&gt;
I kildelisten vil kilden optræde på følgende måde:&lt;br /&gt;
&lt;br /&gt;
Singh, Y., 2018. Arduino Library ADS1115 16 bit 4 channel ADC. [Online] &amp;lt;br /&amp;gt;&lt;br /&gt;
Available at: https://github.com/ncdcommunity/Arduino_Library_ADS1115_16Bit_4Channel_ADC&amp;lt;br /&amp;gt;&lt;br /&gt;
[Senest hentet eller vist den 15 marts 2024].&lt;br /&gt;
&lt;br /&gt;
===ChatGPT som kilde til kode===&lt;br /&gt;
Det følgende er skrevet med udgangspunkt i det der er beskrevet på viden.ai&amp;lt;ref&amp;gt;[https://viden.ai/korrekt-kildehenvisning-af-chatgpt/ Korrekt kildehenvisning af ChatGPT]&amp;lt;/ref&amp;gt;. hvor der angives hvordan man kildehenviser, men også lidt om hvordan man håndterer det i tekst - i korte træk, lav et metodeafsnit, beskriv hvad man gør og vær meget redelig, ved at man angiver hvad man har fået af ChatGPT ved at lægge det ved som et bilag.&lt;br /&gt;
&lt;br /&gt;
Hvis man forstår at prompte fornuftigt, så er ChatGPT faktisk ret god til at foreslå kode, der kan anvendes, men ligesom det er plagiat hvis man kopierer fra nettet, så er det plagiat, hvis man lader ChatGPT skrive store dele af ens program for sig.&lt;br /&gt;
&lt;br /&gt;
Som det er formuleret i vejledningen til både programmering C og B, så kan man anvende ChatGPT til hjælp i fejlfinding af kode. For at kunne kildehenvise korrekt til hjælp med fejlfinding, så skal man angive hvad man har promptet til ChatGPT og hvad den har svaret - det kan placeres i bilag.&lt;br /&gt;
&lt;br /&gt;
En anden ting, som også er OK at få hjælp med er, at komme i gang med programmet - det er denne problematik der her gives et eksempel på. I eksemplet beskrives hvad man skal skrive i sin dokumentation, når man har anvendt denne hjælp, og der er forslag til hvordan man kommer videre i projektet.&lt;br /&gt;
&lt;br /&gt;
Konkret er det starten på udviklingen af et lille spil med bolde i et vindue, udviklet i Processing, der tages udgangspunkt i.&lt;br /&gt;
&lt;br /&gt;
====Metodeafsnit med omtale af ChatGPT====&lt;br /&gt;
Når man anvender CharGPT, så skal man dokumentere hvordan man har gjort det, og hvilke overvejelser der ligger bag det. Det betegnes i rapportskrivning som et metodeafsnit. Det kunne i dette eksempel lyde:&lt;br /&gt;
&lt;br /&gt;
For at få en fornuftig start på programkoden er der brugt ChatGPT til at få rammerne på koden etableret, og til at få et system, så der kan optræde flere bolde i programvinduet. Det er ChatGPT 3.5 (OpenAI, 2023)&amp;lt;ref&amp;gt;[https://chat.openai.com/chat Indgangen til ChatGPT 3.5]&amp;lt;/ref&amp;gt; der er anvendt til denne hjælp. Til programstarten blev der promptet efter at få et programvindue på 800x600 hvor en bold bevæger sig rundt. Den foreslåede kode blev kopieret ind i processings IDE (Processing, 2024)&amp;lt;ref&amp;gt;[https://processing.org Hovedsiden for Processing]&amp;lt;/ref&amp;gt; og testet – den opførte sig som forventet.&lt;br /&gt;
&lt;br /&gt;
Derefter blev der promptet efter at få den bold der bevægede sig til at dele sig op i to, når man klikker på den med musen. Dette resulterede i en væsentligt anderledes kode, som igen blev kopieret ind i processing og testet, og igen med et acceptabelt resultat. Dialogen med ChatGPT (OpenAI, 2023) og herunder de to koder, kan ses i bilag 1.&lt;br /&gt;
&lt;br /&gt;
Herefter er resten af koden udviklet på traditionel vis, hvor første trin var at dokumentere princippet i den foreslåede kode, specielt den Ball klasse der blev introduceret for at kunne arbejde med flere bolde i vinduet.&lt;br /&gt;
&lt;br /&gt;
Det nævnte bilag 1 [[media:ChatGPT-dialog-1.pdf|kan ses i denne PDF]].&lt;br /&gt;
&lt;br /&gt;
====Dokumentation af koden udviklet af ChatGPT====&lt;br /&gt;
Da der skulle kunne dannes nye bolde så oprettes der en klasse, som ChatGPT skriver det i dialogen i Bilag 1:&lt;br /&gt;
&lt;br /&gt;
: &#039;&#039;&amp;quot;Dette kodeeksempel opretter en klasse kaldet Ball, som repræsenterer boldobjekterne. Når musen klikkes, kontrolleres det, om musens position er inden for en bold. Hvis det er tilfældet, oprettes to nye boldobjekter, der bevæger sig i forskellige retninger, og den originale bold fjernes fra arrayet.&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Ved at teste koden kan man se at det ikke er det helt rigtige den formulerer - der oprettes godt nok to nye bold-objekter, men det er ikke den oprindelige bold der fjernes, det er den ene af de ny-oprettede bolde. Det kan ses ved at de to bolde kommer i samme position, og den ene fortsætter i samme retning (den oprindelige), mens den ny-oprettede går i en tilfældig retning. Dette rettes til senere i dokumentationen under &amp;quot;oprettelse af ny bold&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
For at have en god struktur i koden, så placeres klassen Ball i en fil for sig kaldet Ball. Denne fil starter med at definere koden som en klasse med linjen:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
class Ball {&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dernæst defineres klassens egenskaber, der er boldens position og hastighed samt en fast diameter. Ud over det er der en x- og y-retning defineret. Den anvendes til at sige om bolden bevæger sig i en positiv eller negativ retning, så de skifter mellem +1 og -1, når kanterne rammes.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  float x, y;&lt;br /&gt;
  float xspeed, yspeed;&lt;br /&gt;
  int diameter = 30;&lt;br /&gt;
  int xdirection = 1;&lt;br /&gt;
  int ydirection = 1;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der defineres to forskellige constructors til bolden. Den første anvendes til at danne den første bold med, hvor position og hastighed sættes tilfældigt.&lt;br /&gt;
&lt;br /&gt;
Her forudses et problem at der kan komme et randfænomen, hvis bolden dannes, så den ligger med noget uden for skærmen. Da det er tilfældigt; så er det sjældent problemet opstår. For at fremprovokere det oftere er det testet med en diameter på 200, hvor det kunne ses at bolden bliver &amp;quot;hængende&amp;quot; i kanten.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  Ball() {&lt;br /&gt;
    x = random(width);&lt;br /&gt;
    y = random(height);&lt;br /&gt;
    xspeed = random(0.5, 2);&lt;br /&gt;
    yspeed = random(0.5, 2);&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Dette rettes ved at omskrive de constructor til følgende kode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  Ball() {&lt;br /&gt;
    x = random(diameter / 2, width - diameter / 2);&lt;br /&gt;
    y = random(diameter / 2, height - diameter / 2);&lt;br /&gt;
    xspeed = random(0.5, 2);&lt;br /&gt;
    yspeed = random(0.5, 2);&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Den anden constructor tager fire parametre, der er positionen og hastigheden. Denne constructor anvendes, når der skal dannes nye bolde, hvor koden netop skal starte den nye bold i den oprindelige bolds position, og med en ny retning.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  Ball(float x, float y, float xspeed, float yspeed) {&lt;br /&gt;
    this.x = x;&lt;br /&gt;
    this.y = y;&lt;br /&gt;
    this.xspeed = xspeed;&lt;br /&gt;
    this.yspeed = yspeed;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ud over disse standard ting til oprettelsen af objekter, så er der 3 metoder i klassen. Den første er en move() metode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  void move() {&lt;br /&gt;
    x = x + (xspeed * xdirection);&lt;br /&gt;
    y = y + (yspeed * ydirection);&lt;br /&gt;
&lt;br /&gt;
    if ((x + diameter/2 &amp;gt;= width) || (x - diameter/2 &amp;lt;= 0)) {&lt;br /&gt;
      xdirection *= -1;&lt;br /&gt;
    }&lt;br /&gt;
    if ((y + diameter/2 &amp;gt;= height) || (y - diameter/2 &amp;lt;= 0)) {&lt;br /&gt;
      ydirection *= -1;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Måden metoden virker på er at den lægger hastigheden til boldens position (både x og y), og hvis boldens position (både i x og y) er kommet uden for rammen, så ændres retningen for enten x eller y.&lt;br /&gt;
&lt;br /&gt;
For at kunne vise bolden er der en display() metode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  void display() {&lt;br /&gt;
    ellipse(x, y, diameter, diameter);&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Den sidste metode hedder contains(), og den tager en position som parameter til metoden. Der undersøges så om den position ligger inden for bolden ved at se om afstanden mellem boldens center og den testede position er mindre end den halve diameter. Hvis den er inden for bolden, så returneres true, ellers returneres false:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  boolean contains(float x, float y) {&lt;br /&gt;
    float d = dist(x, y, this.x, this.y);&lt;br /&gt;
    if (d &amp;lt; diameter/2) {&lt;br /&gt;
      return true;&lt;br /&gt;
    } else {&lt;br /&gt;
      return false;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Oprettelse af ny bold====&lt;br /&gt;
I den oprindelige kode undersøges om der er klikket på en bold, ved at alle bolde løbes igennem i mousePressed() funktionen, og med metoden contains undersøges om der er klikket på en bold. Denne måde at undersøge alle bolde på beholdes.&lt;br /&gt;
&lt;br /&gt;
Som omtalt er det ikke den smarteste måde til at dele bolden op i to, der anvendes. Som det ses i koden herunder, så appendes der to nye bolde på med den oprindelige bolds x- og y-position på samt tilfældige x- og y-hastigheder. Disse to bolde lægges i slutningen af arrayet. Derefter anvendes shorten&amp;lt;ref&amp;gt;[https://processing.org/reference/shorten_.html Processings shorten metode til arrays]&amp;lt;/ref&amp;gt; til at fjerne et element, men da det element der fjernes er det sidste element i arrayet, så fjernes der bare den sidst oprettede bold.&lt;br /&gt;
&lt;br /&gt;
Hvis man var tilfreds med den opførsel, så kunne man blot fjerne kodelinjen med den anden append og kodelinjen med shorten. Så ville man have samme funktion.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
    if (balls[i].contains(mouseX, mouseY)) {&lt;br /&gt;
      balls = (Ball[]) append(balls, new Ball(balls[i].x, balls[i].y, random(-5, 5), random(-5, 5)));&lt;br /&gt;
      balls = (Ball[]) append(balls, new Ball(balls[i].x, balls[i].y, random(-5, 5), random(-5, 5)));&lt;br /&gt;
      balls = (Ball[]) shorten(balls);&lt;br /&gt;
      break;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Den nye bold der oprettes får bare en tilfældig retning, og den oprindelige bold fortsætter bare i den retning den var på vej i. Det er ikke den opførsel der ønskes i spillet. Der ønskes i stedet at det ser ud som om bolden &amp;quot;splittes op&amp;quot; i 2 bolde, og den opførsel laves ved at lade den oprindelige bold ændre 30 grader til den ene side, og den nye bold får 30 grader til den anden side.&lt;br /&gt;
&lt;br /&gt;
For at gøre dette, så oprettes der en metode multiply() i klassen Ball. Denne metode returnerer en ny bold af typen Ball, så nu kan koden i museklikket skrives som følger:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
    if (balls[i].contains(mouseX, mouseY)) {&lt;br /&gt;
      balls = (Ball[]) append(balls, balls[i].multiply());&lt;br /&gt;
      break;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Som det kan ses, så appendes der en ny bold ind i balls-arrayet, ud fra metoden multiply().&lt;br /&gt;
&lt;br /&gt;
Metoden multiply() oprettes inde i klassen med følgende kode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  Ball multiply() {&lt;br /&gt;
    xspeed *= xdirection;&lt;br /&gt;
    yspeed *= ydirection;&lt;br /&gt;
    xdirection = 1;&lt;br /&gt;
    ydirection = 1;&lt;br /&gt;
    float speed = dist(0, 0, xspeed, yspeed);&lt;br /&gt;
    float angle = acos(xspeed / speed);&lt;br /&gt;
    if (yspeed &amp;lt; 0) angle = 0.0 - angle;&lt;br /&gt;
    speed *= 1.5;&lt;br /&gt;
    xspeed = speed * cos(angle + PI / 6);&lt;br /&gt;
    yspeed = speed * sin(angle + PI / 6);&lt;br /&gt;
    Ball b = new Ball(x, y, speed * cos(angle - PI / 6), speed * sin(angle - PI / 6));&lt;br /&gt;
    return b;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Først regnes retningen over i xspeed og yspeed, så de kan være både positive og negative. På den måde indeholder de to variabler retningen.&lt;br /&gt;
&lt;br /&gt;
Dernæst omregnes x- og y-hastigheden til en samlet hastighed speed og en vinkel angle, som kan være mellem +PI og -PI (+/- 180 grader).&lt;br /&gt;
&lt;br /&gt;
Begge bolde skal bevæge sig hurtigere efter de er delt, så spillet gradvist bliver sværere, derfor ganges hastigheden med 1,5.&lt;br /&gt;
&lt;br /&gt;
Den oprindelige bold får nu en ny retning, ved at udregne x- og y-hastigheden ud fra den nye hastighed og vinklen plus 30 grader.&lt;br /&gt;
&lt;br /&gt;
Til sidst oprettes en ny bold med samme position som den oprindelige og en x- og y-hastighed udregnet fra den oprindelige bolds hastighed og vinklen minus 30 grader. Denne bold returneres fra metoden.&lt;br /&gt;
&lt;br /&gt;
==Referencer== &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt; &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Programmering}}&lt;br /&gt;
&lt;br /&gt;
[[Kategori:Programmering teknik]]&lt;/div&gt;</summary>
		<author><name>Bar</name></author>
	</entry>
	<entry>
		<id>https://www.htxarduino.dk/index.php?title=Programmering_med_ChatGPT&amp;diff=5396</id>
		<title>Programmering med ChatGPT</title>
		<link rel="alternate" type="text/html" href="https://www.htxarduino.dk/index.php?title=Programmering_med_ChatGPT&amp;diff=5396"/>
		<updated>2024-03-17T08:17:28Z</updated>

		<summary type="html">&lt;p&gt;Bar: /* ChatGPT som kilde til kode */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Det er ikke så svært at få ChatGPT&amp;lt;ref&amp;gt;[https://chat.openai.com/auth/login ChatGPT Login] - Indgangen til ChatGPT&amp;lt;/ref&amp;gt; til at lave kode, der skal man blot beskrive hvad man gerne vil have programmet til at gøre, og så kopiere den kode, der kommer ud af det - det giver tit ret gode resultater.&lt;br /&gt;
&lt;br /&gt;
Problemet med at anvende ChatGPT i forbindelse med skoleprojekter er, at man skal have forståelsen med i det, og at man ikke kan blive anklaget for plagiat.&lt;br /&gt;
&lt;br /&gt;
==Hvad må man ikke i en skoleprojekt==&lt;br /&gt;
*Man må ikke kopiere kode, som man ikke selv har skrevet, til et programmeringsprodukt uden at man angiver en kilde. Det er uanset hvor koden stammer fra, også selvom man har brugt ChatGPT til at &amp;quot;udvikle&amp;quot; koden.&lt;br /&gt;
*Man må ikke aflevere et produkt hvor de primære dele af koden er kopieret, heller ikke selvom man kildehenviser.&lt;br /&gt;
*Man må ikke få ChatGPT til at dokumentere sin kode, ved at man kopierer ChatGPT&#039;s beskrivelse ind i sin dokumentation af koden.&lt;br /&gt;
&lt;br /&gt;
De beskrevne eksempler er at betragte som plagiat, og vil blive håndteret efter skolens ordensregler, hvilket i værste fald kan ende med at et fag annulleres eller man bliver bortvist fra uddannelsen.&lt;br /&gt;
==Hvad er tilladt med ChatGPT==&lt;br /&gt;
På samme måde som man må anvende kilder fra internettet, så må man i programmerings-faget i gymnasiet anvende ChatGPT i udviklingen af kode til et programmeringsprodukt. Dette er blevet tilladt via en revidering af vejledningen til faget&amp;lt;ref&amp;gt;[https://www.uvm.dk/-/media/filer/uvm/udd/gym/pdf23/aug/vejledninger/valgfag/230807-programmering-c--valgfag.pdf Vejledning] til Valgfaget Programmering C&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
I vejledningen står der som følger:&lt;br /&gt;
&lt;br /&gt;
: &#039;&#039;&amp;quot;brug af internettet er tilladt som fagligt hjælpemiddel ved de mundtlige prøver, inkluderer de tilladte hjælpemidler anvendelsen af chatbots og lignende på en måde, som afspejler, hvordan man arbejder i den daglige undervisning. Dette kunne fx være brug af ChatGPT til at debugge kode.&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Det skal altså afspejle den normale brug, som man også har ved at bruge internettet. Som angivet under hvad man ikke må, så er den normale brug, at man anvender information til at lære et programmere, men at man ikke tager så meget af sit produkt fra nettet, så man ikke har en forståelse af hvordan produktet er sammensat.&lt;br /&gt;
&lt;br /&gt;
Videre i vejledningen står der:&lt;br /&gt;
&lt;br /&gt;
: &#039;&#039;&amp;quot;I forhold til denne type hjælpemidler er det vigtigt at være opmærksom på, at den tilladte anvendelse er betinget af, at hjælpemidlerne kun benyttes i et omfang, hvor prøvebesvarelsen er selvstændig og udelukkende elevens egen.&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Igen understreges at det der afleveres skal være elevens selvstændigt udviklede produkt og dokumentation, hvor man på normal vis anvender internettet som et værktøj til at bibringe forståelse.&lt;br /&gt;
&lt;br /&gt;
==Problemet med ChatGPT==&lt;br /&gt;
Ligesom man ikke kan kilde-henvise til &amp;quot;google&amp;quot;, for at angive at man har fundet informationer på nettet, så kan man heller ikke kildehenvise til ChatGPT direkte som en kilde.&lt;br /&gt;
&lt;br /&gt;
Når man finder informationer med google&#039;, så skal man angive hvor på nettet man har fundet dem med så præcis en kildehenvisning, at man kan se den information der er blevet anvendt.&lt;br /&gt;
&lt;br /&gt;
Denne type henvisning kan man ikke lave i forhold til ChatGPT, da sprogmodellen der ligger bag ChatGPT konstant udvikler sig, samt at de svar sprogmodellen giver har et randomiseret element indbygget, som er med til at give bedre svar&amp;lt;ref&amp;gt;[https://www.it-vest.dk/arrangementer/sig-webinar-14-marts-2024-kunstig-intelligens-og-chatgpt-hvordan-virker-det-og-skal-vi-bare-opgive-undervisning-og-eksamen Webinar om kunstig intelligens]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Her er man altså nødt til at tage andre metoder i brug, for at kunne dokumentere at man har udviklet sit produkt ordentligt og redeligt.&lt;br /&gt;
&lt;br /&gt;
==Kildehenvisninger i dokumentation==&lt;br /&gt;
Der kan være forskellige standarder for hvordan man kildehenviser i forskellige uddannelser, dette er skrevet med udgangspunkt i at man anvender Word bibliografi-værktøj og her vist med en Harvard-lignende standard&amp;lt;ref&amp;gt;[https://holstebro-htx.dk/index.php/Word_Kildeliste Kildelister] anvendt i Microsoft Word&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Normal Internet-kilde til kode===&lt;br /&gt;
I dette eksempel er der angivet hvordan man ville dokumentere at man har anvendt kode fra et bibliotek til noget hardware på en [[Arduino]]. I det tænkte eksempel er det en 4 kanals AD-konverter&amp;lt;ref&amp;gt;[https://arduinotech.dk/shop/ads1115-module-4-channel-16-bit-i2c-adc-with-pro-gain-amplifier 4 kanals AD-konverter] fra ArduinoTech&amp;lt;/ref&amp;gt;, der er købt som modul.&lt;br /&gt;
&lt;br /&gt;
For at kunne anvende modulet i koden skal der kommunikeres med modulet på en måde, som er angivet i beskrivelsen af modulet - det er dog ikke nødvendigt at sætte sig ind i den grundlæggende kommunikation, hvis man blot ønsker at få værdier ind i sin software. Som en dokumentation for hvordan man anvender biblioteket kan man skrive følgende:&lt;br /&gt;
&lt;br /&gt;
====Eksempel på dokumentation====&lt;br /&gt;
Til at hente værdierne fra den 4 kanals AD-konverter anvendes et bibliotek fundet på GitHub (Singh, 2018) som kan indlæse de analoge spændinger.&lt;br /&gt;
Til at sætte AD-konverteren rigtigt op, til at kunne læse 4 spændinger, så anvendes eksemplet ”ADS1115_SingleEnded.ino” og i setup skrives følgende kode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
    ads.getAddr_ADS1115(ADS1115_DEFAULT_ADDRESS);   // 0x48, 1001 000 (ADDR = GND)&lt;br /&gt;
    ads.setGain(GAIN_TWO);          // 2x gain   +/- 2.048V  1 bit = 0.0625mV (default)&lt;br /&gt;
    ads.setMode(MODE_CONTIN);       // Continuous conversion mode&lt;br /&gt;
    ads.setRate(RATE_128);          // 128SPS (default)&lt;br /&gt;
    ads.setOSMode(OSMODE_SINGLE);   // Set to start a single-conversion&lt;br /&gt;
    ads.begin();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
I [[loop()]] testes i første omgang, om det kan lade sig gøre at læse de 4 kanaler. Dette gøres ved at afvikle følgende testkode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
    address = ads.ads_i2cAddress;&lt;br /&gt;
    Wire.beginTransmission(address);&lt;br /&gt;
    error = Wire.endTransmission();&lt;br /&gt;
    if (error == 0)&lt;br /&gt;
    {&lt;br /&gt;
        int16_t adc0, adc1, adc2, adc3;&lt;br /&gt;
&lt;br /&gt;
        adc0 = ads.Measure_SingleEnded(0);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 1: &amp;quot;);&lt;br /&gt;
        Serial.println(adc0);&lt;br /&gt;
        adc1 = ads.Measure_SingleEnded(1);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 2: &amp;quot;);&lt;br /&gt;
        Serial.println(adc1);&lt;br /&gt;
        adc2 = ads.Measure_SingleEnded(2);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 3: &amp;quot;);&lt;br /&gt;
        Serial.println(adc2);&lt;br /&gt;
        adc3 = ads.Measure_SingleEnded(3);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 4: &amp;quot;);&lt;br /&gt;
        Serial.println(adc3);&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Denne test giver det ønskede resultat.&lt;br /&gt;
&lt;br /&gt;
Ud fra denne beskrivelse viser man, at man tager andres kode, og anvender ind i sit eget projekt, og man angiver præcist i sin beskrivelse hvad man har taget fra andres kode.&lt;br /&gt;
&lt;br /&gt;
I kildelisten vil kilden optræde på følgende måde:&lt;br /&gt;
&lt;br /&gt;
Singh, Y., 2018. Arduino Library ADS1115 16 bit 4 channel ADC. [Online] &amp;lt;br /&amp;gt;&lt;br /&gt;
Available at: https://github.com/ncdcommunity/Arduino_Library_ADS1115_16Bit_4Channel_ADC&amp;lt;br /&amp;gt;&lt;br /&gt;
[Senest hentet eller vist den 15 marts 2024].&lt;br /&gt;
&lt;br /&gt;
===ChatGPT som kilde til kode===&lt;br /&gt;
Det følgende er skrevet med udgangspunkt i det der er beskrevet på viden.ai&amp;lt;ref&amp;gt;[https://viden.ai/korrekt-kildehenvisning-af-chatgpt/ Korrekt kildehenvisning af ChatGPT]&amp;lt;/ref&amp;gt;. hvor der angives hvordan man kildehenviser, men også lidt om hvordan man håndterer det i tekst - i korte træk, lav et metodeafsnit, beskriv hvad man gør og vær meget redelig, ved at man angiver hvad man har fået af ChatGPT ved at lægge det ved som et bilag.&lt;br /&gt;
&lt;br /&gt;
Hvis man forstår at prompte fornuftigt, så er ChatGPT faktisk ret god til at foreslå kode, der kan anvendes, men ligesom det er plagiat hvis man kopierer fra nettet, så er det plagiat, hvis man lader ChatGPT skrive store dele af ens program for sig.&lt;br /&gt;
&lt;br /&gt;
Som det er formuleret i vejledningen til både programmering C og B, så kan man anvende ChatGPT til hjælp i fejlfinding af kode. For at kunne kildehenvise korrekt til hjælp med fejlfinding, så skal man angive hvad man har promptet til ChatGPT og hvad den har svaret - det kan placeres i bilag.&lt;br /&gt;
&lt;br /&gt;
En anden ting, som også er OK at få hjælp med er, at komme i gang med programmet - det er denne problematik der her gives et eksempel på. I eksemplet beskrives hvad man skal skrive i sin dokumentation, når man har anvendt denne hjælp, og der er forslag til hvordan man kommer videre i projektet.&lt;br /&gt;
&lt;br /&gt;
Konkret er det starten på udviklingen af et lille spil med bolde i et vindue, udviklet i Processing, der tages udgangspunkt i.&lt;br /&gt;
&lt;br /&gt;
====Metodeafsnit med omtale af ChatGPT====&lt;br /&gt;
Når man anvender CharGPT, så skal man dokumentere hvordan man har gjort det, og hvilke overvejelser der ligger bag det. Det betegnes i rapportskrivning som et metodeafsnit. Det kunne i dette eksempel lyde:&lt;br /&gt;
&lt;br /&gt;
For at få en fornuftig start på programkoden er der brugt ChatGPT til at få rammerne på koden etableret, og til at få et system, så der kan optræde flere bolde i programvinduet. Det er ChatGPT 3.5 (OpenAI, 2023) der er anvendt til denne hjælp. Til programstarten blev der promptet efter at få et programvindue på 800x600 hvor en bold bevæger sig rundt. Den foreslåede kode blev kopieret ind i processings IDE (Processing, 2024) og testet – den opførte sig som forventet.&lt;br /&gt;
&lt;br /&gt;
Derefter blev der promptet efter at få den bold der bevægede sig til at dele sig op i to, når man klikker på den med musen. Dette resulterede i en væsentligt anderledes kode, som igen blev kopieret ind i processing og testet, og igen med et acceptabelt resultat. Dialogen med ChatGPT (OpenAI, 2023) og herunder de to koder, kan ses i bilag 1.&lt;br /&gt;
&lt;br /&gt;
Herefter er resten af koden udviklet på traditionel vis, hvor første trin var at dokumentere princippet i den foreslåede kode, specielt den Ball klasse der blev introduceret for at kunne arbejde med flere bolde i vinduet.&lt;br /&gt;
&lt;br /&gt;
Det nævnte bilag 1 [[media:ChatGPT-dialog-1.pdf|kan ses i denne PDF]].&lt;br /&gt;
&lt;br /&gt;
====Dokumentation af koden udviklet af ChatGPT====&lt;br /&gt;
Da der skulle kunne dannes nye bolde så oprettes der en klasse, som ChatGPT skriver det i dialogen i Bilag 1:&lt;br /&gt;
&lt;br /&gt;
: &#039;&#039;&amp;quot;Dette kodeeksempel opretter en klasse kaldet Ball, som repræsenterer boldobjekterne. Når musen klikkes, kontrolleres det, om musens position er inden for en bold. Hvis det er tilfældet, oprettes to nye boldobjekter, der bevæger sig i forskellige retninger, og den originale bold fjernes fra arrayet.&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Ved at teste koden kan man se at det ikke er det helt rigtige den formulerer - der oprettes godt nok to nye bold-objekter, men det er ikke den oprindelige bold der fjernes, det er den ene af de ny-oprettede bolde. Det kan ses ved at de to bolde kommer i samme position, og den ene fortsætter i samme retning (den oprindelige), mens den ny-oprettede går i en tilfældig retning. Dette rettes til senere i dokumentationen under &amp;quot;oprettelse af ny bold&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
For at have en god struktur i koden, så placeres klassen Ball i en fil for sig kaldet Ball. Denne fil starter med at definere koden som en klasse med linjen:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
class Ball {&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dernæst defineres klassens egenskaber, der er boldens position og hastighed samt en fast diameter. Ud over det er der en x- og y-retning defineret. Den anvendes til at sige om bolden bevæger sig i en positiv eller negativ retning, så de skifter mellem +1 og -1, når kanterne rammes.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  float x, y;&lt;br /&gt;
  float xspeed, yspeed;&lt;br /&gt;
  int diameter = 30;&lt;br /&gt;
  int xdirection = 1;&lt;br /&gt;
  int ydirection = 1;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der defineres to forskellige constructors til bolden. Den første anvendes til at danne den første bold med, hvor position og hastighed sættes tilfældigt.&lt;br /&gt;
&lt;br /&gt;
Her forudses et problem at der kan komme et randfænomen, hvis bolden dannes, så den ligger med noget uden for skærmen. Da det er tilfældigt; så er det sjældent problemet opstår. For at fremprovokere det oftere er det testet med en diameter på 200, hvor det kunne ses at bolden bliver &amp;quot;hængende&amp;quot; i kanten.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  Ball() {&lt;br /&gt;
    x = random(width);&lt;br /&gt;
    y = random(height);&lt;br /&gt;
    xspeed = random(0.5, 2);&lt;br /&gt;
    yspeed = random(0.5, 2);&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Dette rettes ved at omskrive de constructor til følgende kode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  Ball() {&lt;br /&gt;
    x = random(diameter / 2, width - diameter / 2);&lt;br /&gt;
    y = random(diameter / 2, height - diameter / 2);&lt;br /&gt;
    xspeed = random(0.5, 2);&lt;br /&gt;
    yspeed = random(0.5, 2);&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Den anden constructor tager fire parametre, der er positionen og hastigheden. Denne constructor anvendes, når der skal dannes nye bolde, hvor koden netop skal starte den nye bold i den oprindelige bolds position, og med en ny retning.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  Ball(float x, float y, float xspeed, float yspeed) {&lt;br /&gt;
    this.x = x;&lt;br /&gt;
    this.y = y;&lt;br /&gt;
    this.xspeed = xspeed;&lt;br /&gt;
    this.yspeed = yspeed;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ud over disse standard ting til oprettelsen af objekter, så er der 3 metoder i klassen. Den første er en move() metode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  void move() {&lt;br /&gt;
    x = x + (xspeed * xdirection);&lt;br /&gt;
    y = y + (yspeed * ydirection);&lt;br /&gt;
&lt;br /&gt;
    if ((x + diameter/2 &amp;gt;= width) || (x - diameter/2 &amp;lt;= 0)) {&lt;br /&gt;
      xdirection *= -1;&lt;br /&gt;
    }&lt;br /&gt;
    if ((y + diameter/2 &amp;gt;= height) || (y - diameter/2 &amp;lt;= 0)) {&lt;br /&gt;
      ydirection *= -1;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Måden metoden virker på er at den lægger hastigheden til boldens position (både x og y), og hvis boldens position (både i x og y) er kommet uden for rammen, så ændres retningen for enten x eller y.&lt;br /&gt;
&lt;br /&gt;
For at kunne vise bolden er der en display() metode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  void display() {&lt;br /&gt;
    ellipse(x, y, diameter, diameter);&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Den sidste metode hedder contains(), og den tager en position som parameter til metoden. Der undersøges så om den position ligger inden for bolden ved at se om afstanden mellem boldens center og den testede position er mindre end den halve diameter. Hvis den er inden for bolden, så returneres true, ellers returneres false:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  boolean contains(float x, float y) {&lt;br /&gt;
    float d = dist(x, y, this.x, this.y);&lt;br /&gt;
    if (d &amp;lt; diameter/2) {&lt;br /&gt;
      return true;&lt;br /&gt;
    } else {&lt;br /&gt;
      return false;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Oprettelse af ny bold====&lt;br /&gt;
I den oprindelige kode undersøges om der er klikket på en bold, ved at alle bolde løbes igennem i mousePressed() funktionen, og med metoden contains undersøges om der er klikket på en bold. Denne måde at undersøge alle bolde på beholdes.&lt;br /&gt;
&lt;br /&gt;
Som omtalt er det ikke den smarteste måde til at dele bolden op i to, der anvendes. Som det ses i koden herunder, så appendes der to nye bolde på med den oprindelige bolds x- og y-position på samt tilfældige x- og y-hastigheder. Disse to bolde lægges i slutningen af arrayet. Derefter anvendes shorten&amp;lt;ref&amp;gt;[https://processing.org/reference/shorten_.html Processings shorten metode til arrays]&amp;lt;/ref&amp;gt; til at fjerne et element, men da det element der fjernes er det sidste element i arrayet, så fjernes der bare den sidst oprettede bold.&lt;br /&gt;
&lt;br /&gt;
Hvis man var tilfreds med den opførsel, så kunne man blot fjerne kodelinjen med den anden append og kodelinjen med shorten. Så ville man have samme funktion.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
    if (balls[i].contains(mouseX, mouseY)) {&lt;br /&gt;
      balls = (Ball[]) append(balls, new Ball(balls[i].x, balls[i].y, random(-5, 5), random(-5, 5)));&lt;br /&gt;
      balls = (Ball[]) append(balls, new Ball(balls[i].x, balls[i].y, random(-5, 5), random(-5, 5)));&lt;br /&gt;
      balls = (Ball[]) shorten(balls);&lt;br /&gt;
      break;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Den nye bold der oprettes får bare en tilfældig retning, og den oprindelige bold fortsætter bare i den retning den var på vej i. Det er ikke den opførsel der ønskes i spillet. Der ønskes i stedet at det ser ud som om bolden &amp;quot;splittes op&amp;quot; i 2 bolde, og den opførsel laves ved at lade den oprindelige bold ændre 30 grader til den ene side, og den nye bold får 30 grader til den anden side.&lt;br /&gt;
&lt;br /&gt;
For at gøre dette, så oprettes der en metode multiply() i klassen Ball. Denne metode returnerer en ny bold af typen Ball, så nu kan koden i museklikket skrives som følger:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
    if (balls[i].contains(mouseX, mouseY)) {&lt;br /&gt;
      balls = (Ball[]) append(balls, balls[i].multiply());&lt;br /&gt;
      break;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Som det kan ses, så appendes der en ny bold ind i balls-arrayet, ud fra metoden multiply().&lt;br /&gt;
&lt;br /&gt;
Metoden multiply() oprettes inde i klassen med følgende kode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  Ball multiply() {&lt;br /&gt;
    xspeed *= xdirection;&lt;br /&gt;
    yspeed *= ydirection;&lt;br /&gt;
    xdirection = 1;&lt;br /&gt;
    ydirection = 1;&lt;br /&gt;
    float speed = dist(0, 0, xspeed, yspeed);&lt;br /&gt;
    float angle = acos(xspeed / speed);&lt;br /&gt;
    if (yspeed &amp;lt; 0) angle = 0.0 - angle;&lt;br /&gt;
    speed *= 1.5;&lt;br /&gt;
    xspeed = speed * cos(angle + PI / 6);&lt;br /&gt;
    yspeed = speed * sin(angle + PI / 6);&lt;br /&gt;
    Ball b = new Ball(x, y, speed * cos(angle - PI / 6), speed * sin(angle - PI / 6));&lt;br /&gt;
    return b;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Først regnes retningen over i xspeed og yspeed, så de kan være både positive og negative. På den måde indeholder de to variabler retningen.&lt;br /&gt;
&lt;br /&gt;
Dernæst omregnes x- og y-hastigheden til en samlet hastighed speed og en vinkel angle, som kan være mellem +PI og -PI (+/- 180 grader).&lt;br /&gt;
&lt;br /&gt;
Begge bolde skal bevæge sig hurtigere efter de er delt, så spillet gradvist bliver sværere, derfor ganges hastigheden med 1,5.&lt;br /&gt;
&lt;br /&gt;
Den oprindelige bold får nu en ny retning, ved at udregne x- og y-hastigheden ud fra den nye hastighed og vinklen plus 30 grader.&lt;br /&gt;
&lt;br /&gt;
Til sidst oprettes en ny bold med samme position som den oprindelige og en x- og y-hastighed udregnet fra den oprindelige bolds hastighed og vinklen minus 30 grader. Denne bold returneres fra metoden.&lt;br /&gt;
&lt;br /&gt;
==Referencer== &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt; &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Programmering}}&lt;br /&gt;
&lt;br /&gt;
[[Kategori:Programmering teknik]]&lt;/div&gt;</summary>
		<author><name>Bar</name></author>
	</entry>
	<entry>
		<id>https://www.htxarduino.dk/index.php?title=Programmering_med_ChatGPT&amp;diff=5395</id>
		<title>Programmering med ChatGPT</title>
		<link rel="alternate" type="text/html" href="https://www.htxarduino.dk/index.php?title=Programmering_med_ChatGPT&amp;diff=5395"/>
		<updated>2024-03-17T08:16:49Z</updated>

		<summary type="html">&lt;p&gt;Bar: /* ChatGPT som kilde til kode */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Det er ikke så svært at få ChatGPT&amp;lt;ref&amp;gt;[https://chat.openai.com/auth/login ChatGPT Login] - Indgangen til ChatGPT&amp;lt;/ref&amp;gt; til at lave kode, der skal man blot beskrive hvad man gerne vil have programmet til at gøre, og så kopiere den kode, der kommer ud af det - det giver tit ret gode resultater.&lt;br /&gt;
&lt;br /&gt;
Problemet med at anvende ChatGPT i forbindelse med skoleprojekter er, at man skal have forståelsen med i det, og at man ikke kan blive anklaget for plagiat.&lt;br /&gt;
&lt;br /&gt;
==Hvad må man ikke i en skoleprojekt==&lt;br /&gt;
*Man må ikke kopiere kode, som man ikke selv har skrevet, til et programmeringsprodukt uden at man angiver en kilde. Det er uanset hvor koden stammer fra, også selvom man har brugt ChatGPT til at &amp;quot;udvikle&amp;quot; koden.&lt;br /&gt;
*Man må ikke aflevere et produkt hvor de primære dele af koden er kopieret, heller ikke selvom man kildehenviser.&lt;br /&gt;
*Man må ikke få ChatGPT til at dokumentere sin kode, ved at man kopierer ChatGPT&#039;s beskrivelse ind i sin dokumentation af koden.&lt;br /&gt;
&lt;br /&gt;
De beskrevne eksempler er at betragte som plagiat, og vil blive håndteret efter skolens ordensregler, hvilket i værste fald kan ende med at et fag annulleres eller man bliver bortvist fra uddannelsen.&lt;br /&gt;
==Hvad er tilladt med ChatGPT==&lt;br /&gt;
På samme måde som man må anvende kilder fra internettet, så må man i programmerings-faget i gymnasiet anvende ChatGPT i udviklingen af kode til et programmeringsprodukt. Dette er blevet tilladt via en revidering af vejledningen til faget&amp;lt;ref&amp;gt;[https://www.uvm.dk/-/media/filer/uvm/udd/gym/pdf23/aug/vejledninger/valgfag/230807-programmering-c--valgfag.pdf Vejledning] til Valgfaget Programmering C&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
I vejledningen står der som følger:&lt;br /&gt;
&lt;br /&gt;
: &#039;&#039;&amp;quot;brug af internettet er tilladt som fagligt hjælpemiddel ved de mundtlige prøver, inkluderer de tilladte hjælpemidler anvendelsen af chatbots og lignende på en måde, som afspejler, hvordan man arbejder i den daglige undervisning. Dette kunne fx være brug af ChatGPT til at debugge kode.&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Det skal altså afspejle den normale brug, som man også har ved at bruge internettet. Som angivet under hvad man ikke må, så er den normale brug, at man anvender information til at lære et programmere, men at man ikke tager så meget af sit produkt fra nettet, så man ikke har en forståelse af hvordan produktet er sammensat.&lt;br /&gt;
&lt;br /&gt;
Videre i vejledningen står der:&lt;br /&gt;
&lt;br /&gt;
: &#039;&#039;&amp;quot;I forhold til denne type hjælpemidler er det vigtigt at være opmærksom på, at den tilladte anvendelse er betinget af, at hjælpemidlerne kun benyttes i et omfang, hvor prøvebesvarelsen er selvstændig og udelukkende elevens egen.&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Igen understreges at det der afleveres skal være elevens selvstændigt udviklede produkt og dokumentation, hvor man på normal vis anvender internettet som et værktøj til at bibringe forståelse.&lt;br /&gt;
&lt;br /&gt;
==Problemet med ChatGPT==&lt;br /&gt;
Ligesom man ikke kan kilde-henvise til &amp;quot;google&amp;quot;, for at angive at man har fundet informationer på nettet, så kan man heller ikke kildehenvise til ChatGPT direkte som en kilde.&lt;br /&gt;
&lt;br /&gt;
Når man finder informationer med google&#039;, så skal man angive hvor på nettet man har fundet dem med så præcis en kildehenvisning, at man kan se den information der er blevet anvendt.&lt;br /&gt;
&lt;br /&gt;
Denne type henvisning kan man ikke lave i forhold til ChatGPT, da sprogmodellen der ligger bag ChatGPT konstant udvikler sig, samt at de svar sprogmodellen giver har et randomiseret element indbygget, som er med til at give bedre svar&amp;lt;ref&amp;gt;[https://www.it-vest.dk/arrangementer/sig-webinar-14-marts-2024-kunstig-intelligens-og-chatgpt-hvordan-virker-det-og-skal-vi-bare-opgive-undervisning-og-eksamen Webinar om kunstig intelligens]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Her er man altså nødt til at tage andre metoder i brug, for at kunne dokumentere at man har udviklet sit produkt ordentligt og redeligt.&lt;br /&gt;
&lt;br /&gt;
==Kildehenvisninger i dokumentation==&lt;br /&gt;
Der kan være forskellige standarder for hvordan man kildehenviser i forskellige uddannelser, dette er skrevet med udgangspunkt i at man anvender Word bibliografi-værktøj og her vist med en Harvard-lignende standard&amp;lt;ref&amp;gt;[https://holstebro-htx.dk/index.php/Word_Kildeliste Kildelister] anvendt i Microsoft Word&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Normal Internet-kilde til kode===&lt;br /&gt;
I dette eksempel er der angivet hvordan man ville dokumentere at man har anvendt kode fra et bibliotek til noget hardware på en [[Arduino]]. I det tænkte eksempel er det en 4 kanals AD-konverter&amp;lt;ref&amp;gt;[https://arduinotech.dk/shop/ads1115-module-4-channel-16-bit-i2c-adc-with-pro-gain-amplifier 4 kanals AD-konverter] fra ArduinoTech&amp;lt;/ref&amp;gt;, der er købt som modul.&lt;br /&gt;
&lt;br /&gt;
For at kunne anvende modulet i koden skal der kommunikeres med modulet på en måde, som er angivet i beskrivelsen af modulet - det er dog ikke nødvendigt at sætte sig ind i den grundlæggende kommunikation, hvis man blot ønsker at få værdier ind i sin software. Som en dokumentation for hvordan man anvender biblioteket kan man skrive følgende:&lt;br /&gt;
&lt;br /&gt;
====Eksempel på dokumentation====&lt;br /&gt;
Til at hente værdierne fra den 4 kanals AD-konverter anvendes et bibliotek fundet på GitHub (Singh, 2018) som kan indlæse de analoge spændinger.&lt;br /&gt;
Til at sætte AD-konverteren rigtigt op, til at kunne læse 4 spændinger, så anvendes eksemplet ”ADS1115_SingleEnded.ino” og i setup skrives følgende kode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
    ads.getAddr_ADS1115(ADS1115_DEFAULT_ADDRESS);   // 0x48, 1001 000 (ADDR = GND)&lt;br /&gt;
    ads.setGain(GAIN_TWO);          // 2x gain   +/- 2.048V  1 bit = 0.0625mV (default)&lt;br /&gt;
    ads.setMode(MODE_CONTIN);       // Continuous conversion mode&lt;br /&gt;
    ads.setRate(RATE_128);          // 128SPS (default)&lt;br /&gt;
    ads.setOSMode(OSMODE_SINGLE);   // Set to start a single-conversion&lt;br /&gt;
    ads.begin();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
I [[loop()]] testes i første omgang, om det kan lade sig gøre at læse de 4 kanaler. Dette gøres ved at afvikle følgende testkode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
    address = ads.ads_i2cAddress;&lt;br /&gt;
    Wire.beginTransmission(address);&lt;br /&gt;
    error = Wire.endTransmission();&lt;br /&gt;
    if (error == 0)&lt;br /&gt;
    {&lt;br /&gt;
        int16_t adc0, adc1, adc2, adc3;&lt;br /&gt;
&lt;br /&gt;
        adc0 = ads.Measure_SingleEnded(0);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 1: &amp;quot;);&lt;br /&gt;
        Serial.println(adc0);&lt;br /&gt;
        adc1 = ads.Measure_SingleEnded(1);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 2: &amp;quot;);&lt;br /&gt;
        Serial.println(adc1);&lt;br /&gt;
        adc2 = ads.Measure_SingleEnded(2);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 3: &amp;quot;);&lt;br /&gt;
        Serial.println(adc2);&lt;br /&gt;
        adc3 = ads.Measure_SingleEnded(3);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 4: &amp;quot;);&lt;br /&gt;
        Serial.println(adc3);&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Denne test giver det ønskede resultat.&lt;br /&gt;
&lt;br /&gt;
Ud fra denne beskrivelse viser man, at man tager andres kode, og anvender ind i sit eget projekt, og man angiver præcist i sin beskrivelse hvad man har taget fra andres kode.&lt;br /&gt;
&lt;br /&gt;
I kildelisten vil kilden optræde på følgende måde:&lt;br /&gt;
&lt;br /&gt;
Singh, Y., 2018. Arduino Library ADS1115 16 bit 4 channel ADC. [Online] &amp;lt;br /&amp;gt;&lt;br /&gt;
Available at: https://github.com/ncdcommunity/Arduino_Library_ADS1115_16Bit_4Channel_ADC&amp;lt;br /&amp;gt;&lt;br /&gt;
[Senest hentet eller vist den 15 marts 2024].&lt;br /&gt;
&lt;br /&gt;
===ChatGPT som kilde til kode===&lt;br /&gt;
Det følgende er skrevet med udgangspunkt i det der er beskrevet på viden.ai&amp;lt;ref&amp;gt;[https://viden.ai/korrekt-kildehenvisning-af-chatgpt/ Korrekt kildehenvisning af ChatGPT]&amp;lt;/ref&amp;gt;. hvor der angives hvordan man kildehenviser, men også lidt om hvordan man håndterer det i tekst - i korte træk, lav et metodeafsnit, beskriv hvad man gør og vær meget redelig, ved at man angiver hvad man har fået af ChatGPT ved at lægge det ved som et bilag.&lt;br /&gt;
&lt;br /&gt;
Hvis man forstår at prompte fornuftigt, så er ChatGPT faktisk ret god til at foreslå kode, der kan anvendes, men ligesom det er plagiat hvis man kopierer fra nettet, så er det plagiat, hvis man lader ChatGPT skrive store dele af ens program for sig.&lt;br /&gt;
&lt;br /&gt;
Som det er formuleret i vejledningen til både programmering C og B, så kan man anvende ChatGPT til hjælp i fejlfinding af kode. For at kunne kildehenvise korrekt til hjælp med fejlfinding, så skal man angive hvad man har promptet til ChatGPT og hvad den har svaret - det kan placeres i bilag.&lt;br /&gt;
&lt;br /&gt;
En anden ting, som også er OK at få hjælp med er, at komme i gang med programmet - det er denne problematik der her gives et eksempel på. I eksemplet beskrives hvad man skal skrive i sin dokumentation, når man har anvendt denne hjælp, og der er forslag til hvordan man kommer videre i projektet.&lt;br /&gt;
&lt;br /&gt;
Konkret er det starten på udviklingen af et lille spil med bolde i et vindue, udviklet i Processing- der tages udgangspunkt i.&lt;br /&gt;
&lt;br /&gt;
====Metodeafsnit med omtale af ChatGPT====&lt;br /&gt;
Når man anvender CharGPT, så skal man dokumentere hvordan man har gjort det, og hvilke overvejelser der ligger bag det. Det betegnes i rapportskrivning som et metodeafsnit. Det kunne i dette eksempel lyde:&lt;br /&gt;
&lt;br /&gt;
For at få en fornuftig start på programkoden er der brugt ChatGPT til at få rammerne på koden etableret, og til at få et system, så der kan optræde flere bolde i programvinduet. Det er ChatGPT 3.5 (OpenAI, 2023) der er anvendt til denne hjælp. Til programstarten blev der promptet efter at få et programvindue på 800x600 hvor en bold bevæger sig rundt. Den foreslåede kode blev kopieret ind i processings IDE (Processing, 2024) og testet – den opførte sig som forventet.&lt;br /&gt;
&lt;br /&gt;
Derefter blev der promptet efter at få den bold der bevægede sig til at dele sig op i to, når man klikker på den med musen. Dette resulterede i en væsentligt anderledes kode, som igen blev kopieret ind i processing og testet, og igen med et acceptabelt resultat. Dialogen med ChatGPT (OpenAI, 2023) og herunder de to koder, kan ses i bilag 1.&lt;br /&gt;
&lt;br /&gt;
Herefter er resten af koden udviklet på traditionel vis, hvor første trin var at dokumentere princippet i den foreslåede kode, specielt den Ball klasse der blev introduceret for at kunne arbejde med flere bolde i vinduet.&lt;br /&gt;
&lt;br /&gt;
Det nævnte bilag 1 [[media:ChatGPT-dialog-1.pdf|kan ses i denne PDF]].&lt;br /&gt;
&lt;br /&gt;
====Dokumentation af koden udviklet af ChatGPT====&lt;br /&gt;
Da der skulle kunne dannes nye bolde så oprettes der en klasse, som ChatGPT skriver det i dialogen i Bilag 1:&lt;br /&gt;
&lt;br /&gt;
: &#039;&#039;&amp;quot;Dette kodeeksempel opretter en klasse kaldet Ball, som repræsenterer boldobjekterne. Når musen klikkes, kontrolleres det, om musens position er inden for en bold. Hvis det er tilfældet, oprettes to nye boldobjekter, der bevæger sig i forskellige retninger, og den originale bold fjernes fra arrayet.&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Ved at teste koden kan man se at det ikke er det helt rigtige den formulerer - der oprettes godt nok to nye bold-objekter, men det er ikke den oprindelige bold der fjernes, det er den ene af de ny-oprettede bolde. Det kan ses ved at de to bolde kommer i samme position, og den ene fortsætter i samme retning (den oprindelige), mens den ny-oprettede går i en tilfældig retning. Dette rettes til senere i dokumentationen under &amp;quot;oprettelse af ny bold&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
For at have en god struktur i koden, så placeres klassen Ball i en fil for sig kaldet Ball. Denne fil starter med at definere koden som en klasse med linjen:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
class Ball {&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dernæst defineres klassens egenskaber, der er boldens position og hastighed samt en fast diameter. Ud over det er der en x- og y-retning defineret. Den anvendes til at sige om bolden bevæger sig i en positiv eller negativ retning, så de skifter mellem +1 og -1, når kanterne rammes.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  float x, y;&lt;br /&gt;
  float xspeed, yspeed;&lt;br /&gt;
  int diameter = 30;&lt;br /&gt;
  int xdirection = 1;&lt;br /&gt;
  int ydirection = 1;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der defineres to forskellige constructors til bolden. Den første anvendes til at danne den første bold med, hvor position og hastighed sættes tilfældigt.&lt;br /&gt;
&lt;br /&gt;
Her forudses et problem at der kan komme et randfænomen, hvis bolden dannes, så den ligger med noget uden for skærmen. Da det er tilfældigt; så er det sjældent problemet opstår. For at fremprovokere det oftere er det testet med en diameter på 200, hvor det kunne ses at bolden bliver &amp;quot;hængende&amp;quot; i kanten.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  Ball() {&lt;br /&gt;
    x = random(width);&lt;br /&gt;
    y = random(height);&lt;br /&gt;
    xspeed = random(0.5, 2);&lt;br /&gt;
    yspeed = random(0.5, 2);&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Dette rettes ved at omskrive de constructor til følgende kode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  Ball() {&lt;br /&gt;
    x = random(diameter / 2, width - diameter / 2);&lt;br /&gt;
    y = random(diameter / 2, height - diameter / 2);&lt;br /&gt;
    xspeed = random(0.5, 2);&lt;br /&gt;
    yspeed = random(0.5, 2);&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Den anden constructor tager fire parametre, der er positionen og hastigheden. Denne constructor anvendes, når der skal dannes nye bolde, hvor koden netop skal starte den nye bold i den oprindelige bolds position, og med en ny retning.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  Ball(float x, float y, float xspeed, float yspeed) {&lt;br /&gt;
    this.x = x;&lt;br /&gt;
    this.y = y;&lt;br /&gt;
    this.xspeed = xspeed;&lt;br /&gt;
    this.yspeed = yspeed;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ud over disse standard ting til oprettelsen af objekter, så er der 3 metoder i klassen. Den første er en move() metode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  void move() {&lt;br /&gt;
    x = x + (xspeed * xdirection);&lt;br /&gt;
    y = y + (yspeed * ydirection);&lt;br /&gt;
&lt;br /&gt;
    if ((x + diameter/2 &amp;gt;= width) || (x - diameter/2 &amp;lt;= 0)) {&lt;br /&gt;
      xdirection *= -1;&lt;br /&gt;
    }&lt;br /&gt;
    if ((y + diameter/2 &amp;gt;= height) || (y - diameter/2 &amp;lt;= 0)) {&lt;br /&gt;
      ydirection *= -1;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Måden metoden virker på er at den lægger hastigheden til boldens position (både x og y), og hvis boldens position (både i x og y) er kommet uden for rammen, så ændres retningen for enten x eller y.&lt;br /&gt;
&lt;br /&gt;
For at kunne vise bolden er der en display() metode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  void display() {&lt;br /&gt;
    ellipse(x, y, diameter, diameter);&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Den sidste metode hedder contains(), og den tager en position som parameter til metoden. Der undersøges så om den position ligger inden for bolden ved at se om afstanden mellem boldens center og den testede position er mindre end den halve diameter. Hvis den er inden for bolden, så returneres true, ellers returneres false:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  boolean contains(float x, float y) {&lt;br /&gt;
    float d = dist(x, y, this.x, this.y);&lt;br /&gt;
    if (d &amp;lt; diameter/2) {&lt;br /&gt;
      return true;&lt;br /&gt;
    } else {&lt;br /&gt;
      return false;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Oprettelse af ny bold====&lt;br /&gt;
I den oprindelige kode undersøges om der er klikket på en bold, ved at alle bolde løbes igennem i mousePressed() funktionen, og med metoden contains undersøges om der er klikket på en bold. Denne måde at undersøge alle bolde på beholdes.&lt;br /&gt;
&lt;br /&gt;
Som omtalt er det ikke den smarteste måde til at dele bolden op i to, der anvendes. Som det ses i koden herunder, så appendes der to nye bolde på med den oprindelige bolds x- og y-position på samt tilfældige x- og y-hastigheder. Disse to bolde lægges i slutningen af arrayet. Derefter anvendes shorten&amp;lt;ref&amp;gt;[https://processing.org/reference/shorten_.html Processings shorten metode til arrays]&amp;lt;/ref&amp;gt; til at fjerne et element, men da det element der fjernes er det sidste element i arrayet, så fjernes der bare den sidst oprettede bold.&lt;br /&gt;
&lt;br /&gt;
Hvis man var tilfreds med den opførsel, så kunne man blot fjerne kodelinjen med den anden append og kodelinjen med shorten. Så ville man have samme funktion.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
    if (balls[i].contains(mouseX, mouseY)) {&lt;br /&gt;
      balls = (Ball[]) append(balls, new Ball(balls[i].x, balls[i].y, random(-5, 5), random(-5, 5)));&lt;br /&gt;
      balls = (Ball[]) append(balls, new Ball(balls[i].x, balls[i].y, random(-5, 5), random(-5, 5)));&lt;br /&gt;
      balls = (Ball[]) shorten(balls);&lt;br /&gt;
      break;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Den nye bold der oprettes får bare en tilfældig retning, og den oprindelige bold fortsætter bare i den retning den var på vej i. Det er ikke den opførsel der ønskes i spillet. Der ønskes i stedet at det ser ud som om bolden &amp;quot;splittes op&amp;quot; i 2 bolde, og den opførsel laves ved at lade den oprindelige bold ændre 30 grader til den ene side, og den nye bold får 30 grader til den anden side.&lt;br /&gt;
&lt;br /&gt;
For at gøre dette, så oprettes der en metode multiply() i klassen Ball. Denne metode returnerer en ny bold af typen Ball, så nu kan koden i museklikket skrives som følger:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
    if (balls[i].contains(mouseX, mouseY)) {&lt;br /&gt;
      balls = (Ball[]) append(balls, balls[i].multiply());&lt;br /&gt;
      break;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Som det kan ses, så appendes der en ny bold ind i balls-arrayet, ud fra metoden multiply().&lt;br /&gt;
&lt;br /&gt;
Metoden multiply() oprettes inde i klassen med følgende kode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  Ball multiply() {&lt;br /&gt;
    xspeed *= xdirection;&lt;br /&gt;
    yspeed *= ydirection;&lt;br /&gt;
    xdirection = 1;&lt;br /&gt;
    ydirection = 1;&lt;br /&gt;
    float speed = dist(0, 0, xspeed, yspeed);&lt;br /&gt;
    float angle = acos(xspeed / speed);&lt;br /&gt;
    if (yspeed &amp;lt; 0) angle = 0.0 - angle;&lt;br /&gt;
    speed *= 1.5;&lt;br /&gt;
    xspeed = speed * cos(angle + PI / 6);&lt;br /&gt;
    yspeed = speed * sin(angle + PI / 6);&lt;br /&gt;
    Ball b = new Ball(x, y, speed * cos(angle - PI / 6), speed * sin(angle - PI / 6));&lt;br /&gt;
    return b;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Først regnes retningen over i xspeed og yspeed, så de kan være både positive og negative. På den måde indeholder de to variabler retningen.&lt;br /&gt;
&lt;br /&gt;
Dernæst omregnes x- og y-hastigheden til en samlet hastighed speed og en vinkel angle, som kan være mellem +PI og -PI (+/- 180 grader).&lt;br /&gt;
&lt;br /&gt;
Begge bolde skal bevæge sig hurtigere efter de er delt, så spillet gradvist bliver sværere, derfor ganges hastigheden med 1,5.&lt;br /&gt;
&lt;br /&gt;
Den oprindelige bold får nu en ny retning, ved at udregne x- og y-hastigheden ud fra den nye hastighed og vinklen plus 30 grader.&lt;br /&gt;
&lt;br /&gt;
Til sidst oprettes en ny bold med samme position som den oprindelige og en x- og y-hastighed udregnet fra den oprindelige bolds hastighed og vinklen minus 30 grader. Denne bold returneres fra metoden.&lt;br /&gt;
&lt;br /&gt;
==Referencer== &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt; &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Programmering}}&lt;br /&gt;
&lt;br /&gt;
[[Kategori:Programmering teknik]]&lt;/div&gt;</summary>
		<author><name>Bar</name></author>
	</entry>
	<entry>
		<id>https://www.htxarduino.dk/index.php?title=Programmering_med_ChatGPT&amp;diff=5394</id>
		<title>Programmering med ChatGPT</title>
		<link rel="alternate" type="text/html" href="https://www.htxarduino.dk/index.php?title=Programmering_med_ChatGPT&amp;diff=5394"/>
		<updated>2024-03-17T08:03:25Z</updated>

		<summary type="html">&lt;p&gt;Bar: /* Problemet med ChatGPT */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Det er ikke så svært at få ChatGPT&amp;lt;ref&amp;gt;[https://chat.openai.com/auth/login ChatGPT Login] - Indgangen til ChatGPT&amp;lt;/ref&amp;gt; til at lave kode, der skal man blot beskrive hvad man gerne vil have programmet til at gøre, og så kopiere den kode, der kommer ud af det - det giver tit ret gode resultater.&lt;br /&gt;
&lt;br /&gt;
Problemet med at anvende ChatGPT i forbindelse med skoleprojekter er, at man skal have forståelsen med i det, og at man ikke kan blive anklaget for plagiat.&lt;br /&gt;
&lt;br /&gt;
==Hvad må man ikke i en skoleprojekt==&lt;br /&gt;
*Man må ikke kopiere kode, som man ikke selv har skrevet, til et programmeringsprodukt uden at man angiver en kilde. Det er uanset hvor koden stammer fra, også selvom man har brugt ChatGPT til at &amp;quot;udvikle&amp;quot; koden.&lt;br /&gt;
*Man må ikke aflevere et produkt hvor de primære dele af koden er kopieret, heller ikke selvom man kildehenviser.&lt;br /&gt;
*Man må ikke få ChatGPT til at dokumentere sin kode, ved at man kopierer ChatGPT&#039;s beskrivelse ind i sin dokumentation af koden.&lt;br /&gt;
&lt;br /&gt;
De beskrevne eksempler er at betragte som plagiat, og vil blive håndteret efter skolens ordensregler, hvilket i værste fald kan ende med at et fag annulleres eller man bliver bortvist fra uddannelsen.&lt;br /&gt;
==Hvad er tilladt med ChatGPT==&lt;br /&gt;
På samme måde som man må anvende kilder fra internettet, så må man i programmerings-faget i gymnasiet anvende ChatGPT i udviklingen af kode til et programmeringsprodukt. Dette er blevet tilladt via en revidering af vejledningen til faget&amp;lt;ref&amp;gt;[https://www.uvm.dk/-/media/filer/uvm/udd/gym/pdf23/aug/vejledninger/valgfag/230807-programmering-c--valgfag.pdf Vejledning] til Valgfaget Programmering C&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
I vejledningen står der som følger:&lt;br /&gt;
&lt;br /&gt;
: &#039;&#039;&amp;quot;brug af internettet er tilladt som fagligt hjælpemiddel ved de mundtlige prøver, inkluderer de tilladte hjælpemidler anvendelsen af chatbots og lignende på en måde, som afspejler, hvordan man arbejder i den daglige undervisning. Dette kunne fx være brug af ChatGPT til at debugge kode.&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Det skal altså afspejle den normale brug, som man også har ved at bruge internettet. Som angivet under hvad man ikke må, så er den normale brug, at man anvender information til at lære et programmere, men at man ikke tager så meget af sit produkt fra nettet, så man ikke har en forståelse af hvordan produktet er sammensat.&lt;br /&gt;
&lt;br /&gt;
Videre i vejledningen står der:&lt;br /&gt;
&lt;br /&gt;
: &#039;&#039;&amp;quot;I forhold til denne type hjælpemidler er det vigtigt at være opmærksom på, at den tilladte anvendelse er betinget af, at hjælpemidlerne kun benyttes i et omfang, hvor prøvebesvarelsen er selvstændig og udelukkende elevens egen.&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Igen understreges at det der afleveres skal være elevens selvstændigt udviklede produkt og dokumentation, hvor man på normal vis anvender internettet som et værktøj til at bibringe forståelse.&lt;br /&gt;
&lt;br /&gt;
==Problemet med ChatGPT==&lt;br /&gt;
Ligesom man ikke kan kilde-henvise til &amp;quot;google&amp;quot;, for at angive at man har fundet informationer på nettet, så kan man heller ikke kildehenvise til ChatGPT direkte som en kilde.&lt;br /&gt;
&lt;br /&gt;
Når man finder informationer med google&#039;, så skal man angive hvor på nettet man har fundet dem med så præcis en kildehenvisning, at man kan se den information der er blevet anvendt.&lt;br /&gt;
&lt;br /&gt;
Denne type henvisning kan man ikke lave i forhold til ChatGPT, da sprogmodellen der ligger bag ChatGPT konstant udvikler sig, samt at de svar sprogmodellen giver har et randomiseret element indbygget, som er med til at give bedre svar&amp;lt;ref&amp;gt;[https://www.it-vest.dk/arrangementer/sig-webinar-14-marts-2024-kunstig-intelligens-og-chatgpt-hvordan-virker-det-og-skal-vi-bare-opgive-undervisning-og-eksamen Webinar om kunstig intelligens]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Her er man altså nødt til at tage andre metoder i brug, for at kunne dokumentere at man har udviklet sit produkt ordentligt og redeligt.&lt;br /&gt;
&lt;br /&gt;
==Kildehenvisninger i dokumentation==&lt;br /&gt;
Der kan være forskellige standarder for hvordan man kildehenviser i forskellige uddannelser, dette er skrevet med udgangspunkt i at man anvender Word bibliografi-værktøj og her vist med en Harvard-lignende standard&amp;lt;ref&amp;gt;[https://holstebro-htx.dk/index.php/Word_Kildeliste Kildelister] anvendt i Microsoft Word&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Normal Internet-kilde til kode===&lt;br /&gt;
I dette eksempel er der angivet hvordan man ville dokumentere at man har anvendt kode fra et bibliotek til noget hardware på en [[Arduino]]. I det tænkte eksempel er det en 4 kanals AD-konverter&amp;lt;ref&amp;gt;[https://arduinotech.dk/shop/ads1115-module-4-channel-16-bit-i2c-adc-with-pro-gain-amplifier 4 kanals AD-konverter] fra ArduinoTech&amp;lt;/ref&amp;gt;, der er købt som modul.&lt;br /&gt;
&lt;br /&gt;
For at kunne anvende modulet i koden skal der kommunikeres med modulet på en måde, som er angivet i beskrivelsen af modulet - det er dog ikke nødvendigt at sætte sig ind i den grundlæggende kommunikation, hvis man blot ønsker at få værdier ind i sin software. Som en dokumentation for hvordan man anvender biblioteket kan man skrive følgende:&lt;br /&gt;
&lt;br /&gt;
====Eksempel på dokumentation====&lt;br /&gt;
Til at hente værdierne fra den 4 kanals AD-konverter anvendes et bibliotek fundet på GitHub (Singh, 2018) som kan indlæse de analoge spændinger.&lt;br /&gt;
Til at sætte AD-konverteren rigtigt op, til at kunne læse 4 spændinger, så anvendes eksemplet ”ADS1115_SingleEnded.ino” og i setup skrives følgende kode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
    ads.getAddr_ADS1115(ADS1115_DEFAULT_ADDRESS);   // 0x48, 1001 000 (ADDR = GND)&lt;br /&gt;
    ads.setGain(GAIN_TWO);          // 2x gain   +/- 2.048V  1 bit = 0.0625mV (default)&lt;br /&gt;
    ads.setMode(MODE_CONTIN);       // Continuous conversion mode&lt;br /&gt;
    ads.setRate(RATE_128);          // 128SPS (default)&lt;br /&gt;
    ads.setOSMode(OSMODE_SINGLE);   // Set to start a single-conversion&lt;br /&gt;
    ads.begin();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
I [[loop()]] testes i første omgang, om det kan lade sig gøre at læse de 4 kanaler. Dette gøres ved at afvikle følgende testkode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
    address = ads.ads_i2cAddress;&lt;br /&gt;
    Wire.beginTransmission(address);&lt;br /&gt;
    error = Wire.endTransmission();&lt;br /&gt;
    if (error == 0)&lt;br /&gt;
    {&lt;br /&gt;
        int16_t adc0, adc1, adc2, adc3;&lt;br /&gt;
&lt;br /&gt;
        adc0 = ads.Measure_SingleEnded(0);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 1: &amp;quot;);&lt;br /&gt;
        Serial.println(adc0);&lt;br /&gt;
        adc1 = ads.Measure_SingleEnded(1);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 2: &amp;quot;);&lt;br /&gt;
        Serial.println(adc1);&lt;br /&gt;
        adc2 = ads.Measure_SingleEnded(2);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 3: &amp;quot;);&lt;br /&gt;
        Serial.println(adc2);&lt;br /&gt;
        adc3 = ads.Measure_SingleEnded(3);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 4: &amp;quot;);&lt;br /&gt;
        Serial.println(adc3);&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Denne test giver det ønskede resultat.&lt;br /&gt;
&lt;br /&gt;
Ud fra denne beskrivelse viser man, at man tager andres kode, og anvender ind i sit eget projekt, og man angiver præcist i sin beskrivelse hvad man har taget fra andres kode.&lt;br /&gt;
&lt;br /&gt;
I kildelisten vil kilden optræde på følgende måde:&lt;br /&gt;
&lt;br /&gt;
Singh, Y., 2018. Arduino Library ADS1115 16 bit 4 channel ADC. [Online] &amp;lt;br /&amp;gt;&lt;br /&gt;
Available at: https://github.com/ncdcommunity/Arduino_Library_ADS1115_16Bit_4Channel_ADC&amp;lt;br /&amp;gt;&lt;br /&gt;
[Senest hentet eller vist den 15 marts 2024].&lt;br /&gt;
&lt;br /&gt;
===ChatGPT som kilde til kode===&lt;br /&gt;
Hvis man forstår at prompte fornuftigt, så er ChatGPT faktisk ret god til at foreslå kode, der kan anvendes, men ligesom det er plagiat hvis man kopierer fra nettet, så er det plagiat, hvis man lader ChatGPT skrive store dele af ens program for sig.&lt;br /&gt;
&lt;br /&gt;
Som det er formuleret i vejledningen til både programmering C og B, så kan man anvende ChatGPT til hjælp i fejlfinding af kode. For at kunne kildehenvise korrekt til hjælp med fejlfinding, så skal man angive hvad man har promptet til ChatGPT og hvad den har svaret - det kan placeres i bilag.&lt;br /&gt;
&lt;br /&gt;
En anden ting, som også er OK at få hjælp med er, at komme i gang med programmet - det er denne problematik der her gives et eksempel på. I eksemplet beskrives hvad man skal skrive i sin dokumentation, når man har anvendt denne hjælp, og der er forslag til hvordan man kommer videre i projektet.&lt;br /&gt;
&lt;br /&gt;
Konkret er det starten på udviklingen af et lille spil med bolde i et vindue, udviklet i Processing- der tages udgangspunkt i.&lt;br /&gt;
&lt;br /&gt;
====Metodeafsnit med omtale af ChatGPT====&lt;br /&gt;
Når man anvender CharGPT, så skal man dokumentere hvordan man har gjort det, og hvilke overvejelser der ligger bag det. Det betegnes i rapportskrivning som et metodeafsnit. Det kunne i dette eksempel lyde:&lt;br /&gt;
&lt;br /&gt;
For at få en fornuftig start på programkoden er der brugt ChatGPT til at få rammerne på koden etableret, og til at få et system, så der kan optræde flere bolde i programvinduet. Det er ChatGPT 3.5 (OpenAI, 2023) der er anvendt til denne hjælp. Til programstarten blev der promptet efter at få et programvindue på 800x600 hvor en bold bevæger sig rundt. Den foreslåede kode blev kopieret ind i processings IDE (Processing, 2024) og testet – den opførte sig som forventet.&lt;br /&gt;
&lt;br /&gt;
Derefter blev der promptet efter at få den bold der bevægede sig til at dele sig op i to, når man klikker på den med musen. Dette resulterede i en væsentligt anderledes kode, som igen blev kopieret ind i processing og testet, og igen med et acceptabelt resultat. Dialogen med ChatGPT (OpenAI, 2023) og herunder de to koder, kan ses i bilag 1.&lt;br /&gt;
&lt;br /&gt;
Herefter er resten af koden udviklet på traditionel vis, hvor første trin var at dokumentere princippet i den foreslåede kode, specielt den Ball klasse der blev introduceret for at kunne arbejde med flere bolde i vinduet.&lt;br /&gt;
&lt;br /&gt;
Det nævnte bilag 1 [[media:ChatGPT-dialog-1.pdf|kan ses i denne PDF]].&lt;br /&gt;
&lt;br /&gt;
====Dokumentation af koden udviklet af ChatGPT====&lt;br /&gt;
Da der skulle kunne dannes nye bolde så oprettes der en klasse, som ChatGPT skriver det i dialogen i Bilag 1:&lt;br /&gt;
&lt;br /&gt;
: &#039;&#039;&amp;quot;Dette kodeeksempel opretter en klasse kaldet Ball, som repræsenterer boldobjekterne. Når musen klikkes, kontrolleres det, om musens position er inden for en bold. Hvis det er tilfældet, oprettes to nye boldobjekter, der bevæger sig i forskellige retninger, og den originale bold fjernes fra arrayet.&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Ved at teste koden kan man se at det ikke er det helt rigtige den formulerer - der oprettes godt nok to nye bold-objekter, men det er ikke den oprindelige bold der fjernes, det er den ene af de ny-oprettede bolde. Det kan ses ved at de to bolde kommer i samme position, og den ene fortsætter i samme retning (den oprindelige), mens den ny-oprettede går i en tilfældig retning. Dette rettes til senere i dokumentationen under &amp;quot;oprettelse af ny bold&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
For at have en god struktur i koden, så placeres klassen Ball i en fil for sig kaldet Ball. Denne fil starter med at definere koden som en klasse med linjen:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
class Ball {&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dernæst defineres klassens egenskaber, der er boldens position og hastighed samt en fast diameter. Ud over det er der en x- og y-retning defineret. Den anvendes til at sige om bolden bevæger sig i en positiv eller negativ retning, så de skifter mellem +1 og -1, når kanterne rammes.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  float x, y;&lt;br /&gt;
  float xspeed, yspeed;&lt;br /&gt;
  int diameter = 30;&lt;br /&gt;
  int xdirection = 1;&lt;br /&gt;
  int ydirection = 1;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der defineres to forskellige constructors til bolden. Den første anvendes til at danne den første bold med, hvor position og hastighed sættes tilfældigt.&lt;br /&gt;
&lt;br /&gt;
Her forudses et problem at der kan komme et randfænomen, hvis bolden dannes, så den ligger med noget uden for skærmen. Da det er tilfældigt; så er det sjældent problemet opstår. For at fremprovokere det oftere er det testet med en diameter på 200, hvor det kunne ses at bolden bliver &amp;quot;hængende&amp;quot; i kanten.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  Ball() {&lt;br /&gt;
    x = random(width);&lt;br /&gt;
    y = random(height);&lt;br /&gt;
    xspeed = random(0.5, 2);&lt;br /&gt;
    yspeed = random(0.5, 2);&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Dette rettes ved at omskrive de constructor til følgende kode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  Ball() {&lt;br /&gt;
    x = random(diameter / 2, width - diameter / 2);&lt;br /&gt;
    y = random(diameter / 2, height - diameter / 2);&lt;br /&gt;
    xspeed = random(0.5, 2);&lt;br /&gt;
    yspeed = random(0.5, 2);&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Den anden constructor tager fire parametre, der er positionen og hastigheden. Denne constructor anvendes, når der skal dannes nye bolde, hvor koden netop skal starte den nye bold i den oprindelige bolds position, og med en ny retning.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  Ball(float x, float y, float xspeed, float yspeed) {&lt;br /&gt;
    this.x = x;&lt;br /&gt;
    this.y = y;&lt;br /&gt;
    this.xspeed = xspeed;&lt;br /&gt;
    this.yspeed = yspeed;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ud over disse standard ting til oprettelsen af objekter, så er der 3 metoder i klassen. Den første er en move() metode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  void move() {&lt;br /&gt;
    x = x + (xspeed * xdirection);&lt;br /&gt;
    y = y + (yspeed * ydirection);&lt;br /&gt;
&lt;br /&gt;
    if ((x + diameter/2 &amp;gt;= width) || (x - diameter/2 &amp;lt;= 0)) {&lt;br /&gt;
      xdirection *= -1;&lt;br /&gt;
    }&lt;br /&gt;
    if ((y + diameter/2 &amp;gt;= height) || (y - diameter/2 &amp;lt;= 0)) {&lt;br /&gt;
      ydirection *= -1;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Måden metoden virker på er at den lægger hastigheden til boldens position (både x og y), og hvis boldens position (både i x og y) er kommet uden for rammen, så ændres retningen for enten x eller y.&lt;br /&gt;
&lt;br /&gt;
For at kunne vise bolden er der en display() metode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  void display() {&lt;br /&gt;
    ellipse(x, y, diameter, diameter);&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Den sidste metode hedder contains(), og den tager en position som parameter til metoden. Der undersøges så om den position ligger inden for bolden ved at se om afstanden mellem boldens center og den testede position er mindre end den halve diameter. Hvis den er inden for bolden, så returneres true, ellers returneres false:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  boolean contains(float x, float y) {&lt;br /&gt;
    float d = dist(x, y, this.x, this.y);&lt;br /&gt;
    if (d &amp;lt; diameter/2) {&lt;br /&gt;
      return true;&lt;br /&gt;
    } else {&lt;br /&gt;
      return false;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Oprettelse af ny bold====&lt;br /&gt;
I den oprindelige kode undersøges om der er klikket på en bold, ved at alle bolde løbes igennem i mousePressed() funktionen, og med metoden contains undersøges om der er klikket på en bold. Denne måde at undersøge alle bolde på beholdes.&lt;br /&gt;
&lt;br /&gt;
Som omtalt er det ikke den smarteste måde til at dele bolden op i to, der anvendes. Som det ses i koden herunder, så appendes der to nye bolde på med den oprindelige bolds x- og y-position på samt tilfældige x- og y-hastigheder. Disse to bolde lægges i slutningen af arrayet. Derefter anvendes shorten&amp;lt;ref&amp;gt;[https://processing.org/reference/shorten_.html Processings shorten metode til arrays]&amp;lt;/ref&amp;gt; til at fjerne et element, men da det element der fjernes er det sidste element i arrayet, så fjernes der bare den sidst oprettede bold.&lt;br /&gt;
&lt;br /&gt;
Hvis man var tilfreds med den opførsel, så kunne man blot fjerne kodelinjen med den anden append og kodelinjen med shorten. Så ville man have samme funktion.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
    if (balls[i].contains(mouseX, mouseY)) {&lt;br /&gt;
      balls = (Ball[]) append(balls, new Ball(balls[i].x, balls[i].y, random(-5, 5), random(-5, 5)));&lt;br /&gt;
      balls = (Ball[]) append(balls, new Ball(balls[i].x, balls[i].y, random(-5, 5), random(-5, 5)));&lt;br /&gt;
      balls = (Ball[]) shorten(balls);&lt;br /&gt;
      break;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Den nye bold der oprettes får bare en tilfældig retning, og den oprindelige bold fortsætter bare i den retning den var på vej i. Det er ikke den opførsel der ønskes i spillet. Der ønskes i stedet at det ser ud som om bolden &amp;quot;splittes op&amp;quot; i 2 bolde, og den opførsel laves ved at lade den oprindelige bold ændre 30 grader til den ene side, og den nye bold får 30 grader til den anden side.&lt;br /&gt;
&lt;br /&gt;
For at gøre dette, så oprettes der en metode multiply() i klassen Ball. Denne metode returnerer en ny bold af typen Ball, så nu kan koden i museklikket skrives som følger:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
    if (balls[i].contains(mouseX, mouseY)) {&lt;br /&gt;
      balls = (Ball[]) append(balls, balls[i].multiply());&lt;br /&gt;
      break;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Som det kan ses, så appendes der en ny bold ind i balls-arrayet, ud fra metoden multiply().&lt;br /&gt;
&lt;br /&gt;
Metoden multiply() oprettes inde i klassen med følgende kode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  Ball multiply() {&lt;br /&gt;
    xspeed *= xdirection;&lt;br /&gt;
    yspeed *= ydirection;&lt;br /&gt;
    xdirection = 1;&lt;br /&gt;
    ydirection = 1;&lt;br /&gt;
    float speed = dist(0, 0, xspeed, yspeed);&lt;br /&gt;
    float angle = acos(xspeed / speed);&lt;br /&gt;
    if (yspeed &amp;lt; 0) angle = 0.0 - angle;&lt;br /&gt;
    speed *= 1.5;&lt;br /&gt;
    xspeed = speed * cos(angle + PI / 6);&lt;br /&gt;
    yspeed = speed * sin(angle + PI / 6);&lt;br /&gt;
    Ball b = new Ball(x, y, speed * cos(angle - PI / 6), speed * sin(angle - PI / 6));&lt;br /&gt;
    return b;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Først regnes retningen over i xspeed og yspeed, så de kan være både positive og negative. På den måde indeholder de to variabler retningen.&lt;br /&gt;
&lt;br /&gt;
Dernæst omregnes x- og y-hastigheden til en samlet hastighed speed og en vinkel angle, som kan være mellem +PI og -PI (+/- 180 grader).&lt;br /&gt;
&lt;br /&gt;
Begge bolde skal bevæge sig hurtigere efter de er delt, så spillet gradvist bliver sværere, derfor ganges hastigheden med 1,5.&lt;br /&gt;
&lt;br /&gt;
Den oprindelige bold får nu en ny retning, ved at udregne x- og y-hastigheden ud fra den nye hastighed og vinklen plus 30 grader.&lt;br /&gt;
&lt;br /&gt;
Til sidst oprettes en ny bold med samme position som den oprindelige og en x- og y-hastighed udregnet fra den oprindelige bolds hastighed og vinklen minus 30 grader. Denne bold returneres fra metoden.&lt;br /&gt;
==Referencer== &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt; &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Programmering}}&lt;br /&gt;
&lt;br /&gt;
[[Kategori:Programmering teknik]]&lt;/div&gt;</summary>
		<author><name>Bar</name></author>
	</entry>
	<entry>
		<id>https://www.htxarduino.dk/index.php?title=Programmering_med_ChatGPT&amp;diff=5393</id>
		<title>Programmering med ChatGPT</title>
		<link rel="alternate" type="text/html" href="https://www.htxarduino.dk/index.php?title=Programmering_med_ChatGPT&amp;diff=5393"/>
		<updated>2024-03-17T07:59:38Z</updated>

		<summary type="html">&lt;p&gt;Bar: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Det er ikke så svært at få ChatGPT&amp;lt;ref&amp;gt;[https://chat.openai.com/auth/login ChatGPT Login] - Indgangen til ChatGPT&amp;lt;/ref&amp;gt; til at lave kode, der skal man blot beskrive hvad man gerne vil have programmet til at gøre, og så kopiere den kode, der kommer ud af det - det giver tit ret gode resultater.&lt;br /&gt;
&lt;br /&gt;
Problemet med at anvende ChatGPT i forbindelse med skoleprojekter er, at man skal have forståelsen med i det, og at man ikke kan blive anklaget for plagiat.&lt;br /&gt;
&lt;br /&gt;
==Hvad må man ikke i en skoleprojekt==&lt;br /&gt;
*Man må ikke kopiere kode, som man ikke selv har skrevet, til et programmeringsprodukt uden at man angiver en kilde. Det er uanset hvor koden stammer fra, også selvom man har brugt ChatGPT til at &amp;quot;udvikle&amp;quot; koden.&lt;br /&gt;
*Man må ikke aflevere et produkt hvor de primære dele af koden er kopieret, heller ikke selvom man kildehenviser.&lt;br /&gt;
*Man må ikke få ChatGPT til at dokumentere sin kode, ved at man kopierer ChatGPT&#039;s beskrivelse ind i sin dokumentation af koden.&lt;br /&gt;
&lt;br /&gt;
De beskrevne eksempler er at betragte som plagiat, og vil blive håndteret efter skolens ordensregler, hvilket i værste fald kan ende med at et fag annulleres eller man bliver bortvist fra uddannelsen.&lt;br /&gt;
==Hvad er tilladt med ChatGPT==&lt;br /&gt;
På samme måde som man må anvende kilder fra internettet, så må man i programmerings-faget i gymnasiet anvende ChatGPT i udviklingen af kode til et programmeringsprodukt. Dette er blevet tilladt via en revidering af vejledningen til faget&amp;lt;ref&amp;gt;[https://www.uvm.dk/-/media/filer/uvm/udd/gym/pdf23/aug/vejledninger/valgfag/230807-programmering-c--valgfag.pdf Vejledning] til Valgfaget Programmering C&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
I vejledningen står der som følger:&lt;br /&gt;
&lt;br /&gt;
: &#039;&#039;&amp;quot;brug af internettet er tilladt som fagligt hjælpemiddel ved de mundtlige prøver, inkluderer de tilladte hjælpemidler anvendelsen af chatbots og lignende på en måde, som afspejler, hvordan man arbejder i den daglige undervisning. Dette kunne fx være brug af ChatGPT til at debugge kode.&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Det skal altså afspejle den normale brug, som man også har ved at bruge internettet. Som angivet under hvad man ikke må, så er den normale brug, at man anvender information til at lære et programmere, men at man ikke tager så meget af sit produkt fra nettet, så man ikke har en forståelse af hvordan produktet er sammensat.&lt;br /&gt;
&lt;br /&gt;
Videre i vejledningen står der:&lt;br /&gt;
&lt;br /&gt;
: &#039;&#039;&amp;quot;I forhold til denne type hjælpemidler er det vigtigt at være opmærksom på, at den tilladte anvendelse er betinget af, at hjælpemidlerne kun benyttes i et omfang, hvor prøvebesvarelsen er selvstændig og udelukkende elevens egen.&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Igen understreges at det der afleveres skal være elevens selvstændigt udviklede produkt og dokumentation, hvor man på normal vis anvender internettet som et værktøj til at bibringe forståelse.&lt;br /&gt;
&lt;br /&gt;
==Problemet med ChatGPT==&lt;br /&gt;
Ligesom man ikke kan kilde-henvise til &amp;quot;google&amp;quot;, for at angive at man har fundet informationer på nettet, så kan man heller ikke kildehenvise til ChatGPT direkte som en kilde.&lt;br /&gt;
&lt;br /&gt;
Når man finder informationer med google&#039;, så skal man angive hvor på nettet man har fundet dem med så præcis en kildehenvisning, at man kan se den information der er blevet anvendt.&lt;br /&gt;
&lt;br /&gt;
Denne type henvisning kan man ikke lave i forhold til ChatGPT, da sprogmodellen der ligger bag ChatGPT konstant udvikler sig, samt at de svar sprogmodellen giver her et randomiseret element indbygget, som er med til at give bedre svar&amp;lt;ref&amp;gt;[https://www.it-vest.dk/arrangementer/sig-webinar-14-marts-2024-kunstig-intelligens-og-chatgpt-hvordan-virker-det-og-skal-vi-bare-opgive-undervisning-og-eksamen Webinar om kunstig intelligens]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Her er man altså nødt til at tage andre metoder i brug, for at kunne dokumentere at man har udviklet sit produkt ordentligt og redeligt.&lt;br /&gt;
==Kildehenvisninger i dokumentation==&lt;br /&gt;
Der kan være forskellige standarder for hvordan man kildehenviser i forskellige uddannelser, dette er skrevet med udgangspunkt i at man anvender Word bibliografi-værktøj og her vist med en Harvard-lignende standard&amp;lt;ref&amp;gt;[https://holstebro-htx.dk/index.php/Word_Kildeliste Kildelister] anvendt i Microsoft Word&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Normal Internet-kilde til kode===&lt;br /&gt;
I dette eksempel er der angivet hvordan man ville dokumentere at man har anvendt kode fra et bibliotek til noget hardware på en [[Arduino]]. I det tænkte eksempel er det en 4 kanals AD-konverter&amp;lt;ref&amp;gt;[https://arduinotech.dk/shop/ads1115-module-4-channel-16-bit-i2c-adc-with-pro-gain-amplifier 4 kanals AD-konverter] fra ArduinoTech&amp;lt;/ref&amp;gt;, der er købt som modul.&lt;br /&gt;
&lt;br /&gt;
For at kunne anvende modulet i koden skal der kommunikeres med modulet på en måde, som er angivet i beskrivelsen af modulet - det er dog ikke nødvendigt at sætte sig ind i den grundlæggende kommunikation, hvis man blot ønsker at få værdier ind i sin software. Som en dokumentation for hvordan man anvender biblioteket kan man skrive følgende:&lt;br /&gt;
&lt;br /&gt;
====Eksempel på dokumentation====&lt;br /&gt;
Til at hente værdierne fra den 4 kanals AD-konverter anvendes et bibliotek fundet på GitHub (Singh, 2018) som kan indlæse de analoge spændinger.&lt;br /&gt;
Til at sætte AD-konverteren rigtigt op, til at kunne læse 4 spændinger, så anvendes eksemplet ”ADS1115_SingleEnded.ino” og i setup skrives følgende kode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
    ads.getAddr_ADS1115(ADS1115_DEFAULT_ADDRESS);   // 0x48, 1001 000 (ADDR = GND)&lt;br /&gt;
    ads.setGain(GAIN_TWO);          // 2x gain   +/- 2.048V  1 bit = 0.0625mV (default)&lt;br /&gt;
    ads.setMode(MODE_CONTIN);       // Continuous conversion mode&lt;br /&gt;
    ads.setRate(RATE_128);          // 128SPS (default)&lt;br /&gt;
    ads.setOSMode(OSMODE_SINGLE);   // Set to start a single-conversion&lt;br /&gt;
    ads.begin();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
I [[loop()]] testes i første omgang, om det kan lade sig gøre at læse de 4 kanaler. Dette gøres ved at afvikle følgende testkode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
    address = ads.ads_i2cAddress;&lt;br /&gt;
    Wire.beginTransmission(address);&lt;br /&gt;
    error = Wire.endTransmission();&lt;br /&gt;
    if (error == 0)&lt;br /&gt;
    {&lt;br /&gt;
        int16_t adc0, adc1, adc2, adc3;&lt;br /&gt;
&lt;br /&gt;
        adc0 = ads.Measure_SingleEnded(0);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 1: &amp;quot;);&lt;br /&gt;
        Serial.println(adc0);&lt;br /&gt;
        adc1 = ads.Measure_SingleEnded(1);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 2: &amp;quot;);&lt;br /&gt;
        Serial.println(adc1);&lt;br /&gt;
        adc2 = ads.Measure_SingleEnded(2);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 3: &amp;quot;);&lt;br /&gt;
        Serial.println(adc2);&lt;br /&gt;
        adc3 = ads.Measure_SingleEnded(3);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 4: &amp;quot;);&lt;br /&gt;
        Serial.println(adc3);&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Denne test giver det ønskede resultat.&lt;br /&gt;
&lt;br /&gt;
Ud fra denne beskrivelse viser man, at man tager andres kode, og anvender ind i sit eget projekt, og man angiver præcist i sin beskrivelse hvad man har taget fra andres kode.&lt;br /&gt;
&lt;br /&gt;
I kildelisten vil kilden optræde på følgende måde:&lt;br /&gt;
&lt;br /&gt;
Singh, Y., 2018. Arduino Library ADS1115 16 bit 4 channel ADC. [Online] &amp;lt;br /&amp;gt;&lt;br /&gt;
Available at: https://github.com/ncdcommunity/Arduino_Library_ADS1115_16Bit_4Channel_ADC&amp;lt;br /&amp;gt;&lt;br /&gt;
[Senest hentet eller vist den 15 marts 2024].&lt;br /&gt;
&lt;br /&gt;
===ChatGPT som kilde til kode===&lt;br /&gt;
Hvis man forstår at prompte fornuftigt, så er ChatGPT faktisk ret god til at foreslå kode, der kan anvendes, men ligesom det er plagiat hvis man kopierer fra nettet, så er det plagiat, hvis man lader ChatGPT skrive store dele af ens program for sig.&lt;br /&gt;
&lt;br /&gt;
Som det er formuleret i vejledningen til både programmering C og B, så kan man anvende ChatGPT til hjælp i fejlfinding af kode. For at kunne kildehenvise korrekt til hjælp med fejlfinding, så skal man angive hvad man har promptet til ChatGPT og hvad den har svaret - det kan placeres i bilag.&lt;br /&gt;
&lt;br /&gt;
En anden ting, som også er OK at få hjælp med er, at komme i gang med programmet - det er denne problematik der her gives et eksempel på. I eksemplet beskrives hvad man skal skrive i sin dokumentation, når man har anvendt denne hjælp, og der er forslag til hvordan man kommer videre i projektet.&lt;br /&gt;
&lt;br /&gt;
Konkret er det starten på udviklingen af et lille spil med bolde i et vindue, udviklet i Processing- der tages udgangspunkt i.&lt;br /&gt;
&lt;br /&gt;
====Metodeafsnit med omtale af ChatGPT====&lt;br /&gt;
Når man anvender CharGPT, så skal man dokumentere hvordan man har gjort det, og hvilke overvejelser der ligger bag det. Det betegnes i rapportskrivning som et metodeafsnit. Det kunne i dette eksempel lyde:&lt;br /&gt;
&lt;br /&gt;
For at få en fornuftig start på programkoden er der brugt ChatGPT til at få rammerne på koden etableret, og til at få et system, så der kan optræde flere bolde i programvinduet. Det er ChatGPT 3.5 (OpenAI, 2023) der er anvendt til denne hjælp. Til programstarten blev der promptet efter at få et programvindue på 800x600 hvor en bold bevæger sig rundt. Den foreslåede kode blev kopieret ind i processings IDE (Processing, 2024) og testet – den opførte sig som forventet.&lt;br /&gt;
&lt;br /&gt;
Derefter blev der promptet efter at få den bold der bevægede sig til at dele sig op i to, når man klikker på den med musen. Dette resulterede i en væsentligt anderledes kode, som igen blev kopieret ind i processing og testet, og igen med et acceptabelt resultat. Dialogen med ChatGPT (OpenAI, 2023) og herunder de to koder, kan ses i bilag 1.&lt;br /&gt;
&lt;br /&gt;
Herefter er resten af koden udviklet på traditionel vis, hvor første trin var at dokumentere princippet i den foreslåede kode, specielt den Ball klasse der blev introduceret for at kunne arbejde med flere bolde i vinduet.&lt;br /&gt;
&lt;br /&gt;
Det nævnte bilag 1 [[media:ChatGPT-dialog-1.pdf|kan ses i denne PDF]].&lt;br /&gt;
&lt;br /&gt;
====Dokumentation af koden udviklet af ChatGPT====&lt;br /&gt;
Da der skulle kunne dannes nye bolde så oprettes der en klasse, som ChatGPT skriver det i dialogen i Bilag 1:&lt;br /&gt;
&lt;br /&gt;
: &#039;&#039;&amp;quot;Dette kodeeksempel opretter en klasse kaldet Ball, som repræsenterer boldobjekterne. Når musen klikkes, kontrolleres det, om musens position er inden for en bold. Hvis det er tilfældet, oprettes to nye boldobjekter, der bevæger sig i forskellige retninger, og den originale bold fjernes fra arrayet.&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Ved at teste koden kan man se at det ikke er det helt rigtige den formulerer - der oprettes godt nok to nye bold-objekter, men det er ikke den oprindelige bold der fjernes, det er den ene af de ny-oprettede bolde. Det kan ses ved at de to bolde kommer i samme position, og den ene fortsætter i samme retning (den oprindelige), mens den ny-oprettede går i en tilfældig retning. Dette rettes til senere i dokumentationen under &amp;quot;oprettelse af ny bold&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
For at have en god struktur i koden, så placeres klassen Ball i en fil for sig kaldet Ball. Denne fil starter med at definere koden som en klasse med linjen:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
class Ball {&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dernæst defineres klassens egenskaber, der er boldens position og hastighed samt en fast diameter. Ud over det er der en x- og y-retning defineret. Den anvendes til at sige om bolden bevæger sig i en positiv eller negativ retning, så de skifter mellem +1 og -1, når kanterne rammes.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  float x, y;&lt;br /&gt;
  float xspeed, yspeed;&lt;br /&gt;
  int diameter = 30;&lt;br /&gt;
  int xdirection = 1;&lt;br /&gt;
  int ydirection = 1;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der defineres to forskellige constructors til bolden. Den første anvendes til at danne den første bold med, hvor position og hastighed sættes tilfældigt.&lt;br /&gt;
&lt;br /&gt;
Her forudses et problem at der kan komme et randfænomen, hvis bolden dannes, så den ligger med noget uden for skærmen. Da det er tilfældigt; så er det sjældent problemet opstår. For at fremprovokere det oftere er det testet med en diameter på 200, hvor det kunne ses at bolden bliver &amp;quot;hængende&amp;quot; i kanten.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  Ball() {&lt;br /&gt;
    x = random(width);&lt;br /&gt;
    y = random(height);&lt;br /&gt;
    xspeed = random(0.5, 2);&lt;br /&gt;
    yspeed = random(0.5, 2);&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Dette rettes ved at omskrive de constructor til følgende kode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  Ball() {&lt;br /&gt;
    x = random(diameter / 2, width - diameter / 2);&lt;br /&gt;
    y = random(diameter / 2, height - diameter / 2);&lt;br /&gt;
    xspeed = random(0.5, 2);&lt;br /&gt;
    yspeed = random(0.5, 2);&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Den anden constructor tager fire parametre, der er positionen og hastigheden. Denne constructor anvendes, når der skal dannes nye bolde, hvor koden netop skal starte den nye bold i den oprindelige bolds position, og med en ny retning.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  Ball(float x, float y, float xspeed, float yspeed) {&lt;br /&gt;
    this.x = x;&lt;br /&gt;
    this.y = y;&lt;br /&gt;
    this.xspeed = xspeed;&lt;br /&gt;
    this.yspeed = yspeed;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ud over disse standard ting til oprettelsen af objekter, så er der 3 metoder i klassen. Den første er en move() metode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  void move() {&lt;br /&gt;
    x = x + (xspeed * xdirection);&lt;br /&gt;
    y = y + (yspeed * ydirection);&lt;br /&gt;
&lt;br /&gt;
    if ((x + diameter/2 &amp;gt;= width) || (x - diameter/2 &amp;lt;= 0)) {&lt;br /&gt;
      xdirection *= -1;&lt;br /&gt;
    }&lt;br /&gt;
    if ((y + diameter/2 &amp;gt;= height) || (y - diameter/2 &amp;lt;= 0)) {&lt;br /&gt;
      ydirection *= -1;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Måden metoden virker på er at den lægger hastigheden til boldens position (både x og y), og hvis boldens position (både i x og y) er kommet uden for rammen, så ændres retningen for enten x eller y.&lt;br /&gt;
&lt;br /&gt;
For at kunne vise bolden er der en display() metode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  void display() {&lt;br /&gt;
    ellipse(x, y, diameter, diameter);&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Den sidste metode hedder contains(), og den tager en position som parameter til metoden. Der undersøges så om den position ligger inden for bolden ved at se om afstanden mellem boldens center og den testede position er mindre end den halve diameter. Hvis den er inden for bolden, så returneres true, ellers returneres false:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  boolean contains(float x, float y) {&lt;br /&gt;
    float d = dist(x, y, this.x, this.y);&lt;br /&gt;
    if (d &amp;lt; diameter/2) {&lt;br /&gt;
      return true;&lt;br /&gt;
    } else {&lt;br /&gt;
      return false;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Oprettelse af ny bold====&lt;br /&gt;
I den oprindelige kode undersøges om der er klikket på en bold, ved at alle bolde løbes igennem i mousePressed() funktionen, og med metoden contains undersøges om der er klikket på en bold. Denne måde at undersøge alle bolde på beholdes.&lt;br /&gt;
&lt;br /&gt;
Som omtalt er det ikke den smarteste måde til at dele bolden op i to, der anvendes. Som det ses i koden herunder, så appendes der to nye bolde på med den oprindelige bolds x- og y-position på samt tilfældige x- og y-hastigheder. Disse to bolde lægges i slutningen af arrayet. Derefter anvendes shorten&amp;lt;ref&amp;gt;[https://processing.org/reference/shorten_.html Processings shorten metode til arrays]&amp;lt;/ref&amp;gt; til at fjerne et element, men da det element der fjernes er det sidste element i arrayet, så fjernes der bare den sidst oprettede bold.&lt;br /&gt;
&lt;br /&gt;
Hvis man var tilfreds med den opførsel, så kunne man blot fjerne kodelinjen med den anden append og kodelinjen med shorten. Så ville man have samme funktion.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
    if (balls[i].contains(mouseX, mouseY)) {&lt;br /&gt;
      balls = (Ball[]) append(balls, new Ball(balls[i].x, balls[i].y, random(-5, 5), random(-5, 5)));&lt;br /&gt;
      balls = (Ball[]) append(balls, new Ball(balls[i].x, balls[i].y, random(-5, 5), random(-5, 5)));&lt;br /&gt;
      balls = (Ball[]) shorten(balls);&lt;br /&gt;
      break;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Den nye bold der oprettes får bare en tilfældig retning, og den oprindelige bold fortsætter bare i den retning den var på vej i. Det er ikke den opførsel der ønskes i spillet. Der ønskes i stedet at det ser ud som om bolden &amp;quot;splittes op&amp;quot; i 2 bolde, og den opførsel laves ved at lade den oprindelige bold ændre 30 grader til den ene side, og den nye bold får 30 grader til den anden side.&lt;br /&gt;
&lt;br /&gt;
For at gøre dette, så oprettes der en metode multiply() i klassen Ball. Denne metode returnerer en ny bold af typen Ball, så nu kan koden i museklikket skrives som følger:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
    if (balls[i].contains(mouseX, mouseY)) {&lt;br /&gt;
      balls = (Ball[]) append(balls, balls[i].multiply());&lt;br /&gt;
      break;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Som det kan ses, så appendes der en ny bold ind i balls-arrayet, ud fra metoden multiply().&lt;br /&gt;
&lt;br /&gt;
Metoden multiply() oprettes inde i klassen med følgende kode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  Ball multiply() {&lt;br /&gt;
    xspeed *= xdirection;&lt;br /&gt;
    yspeed *= ydirection;&lt;br /&gt;
    xdirection = 1;&lt;br /&gt;
    ydirection = 1;&lt;br /&gt;
    float speed = dist(0, 0, xspeed, yspeed);&lt;br /&gt;
    float angle = acos(xspeed / speed);&lt;br /&gt;
    if (yspeed &amp;lt; 0) angle = 0.0 - angle;&lt;br /&gt;
    speed *= 1.5;&lt;br /&gt;
    xspeed = speed * cos(angle + PI / 6);&lt;br /&gt;
    yspeed = speed * sin(angle + PI / 6);&lt;br /&gt;
    Ball b = new Ball(x, y, speed * cos(angle - PI / 6), speed * sin(angle - PI / 6));&lt;br /&gt;
    return b;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Først regnes retningen over i xspeed og yspeed, så de kan være både positive og negative. På den måde indeholder de to variabler retningen.&lt;br /&gt;
&lt;br /&gt;
Dernæst omregnes x- og y-hastigheden til en samlet hastighed speed og en vinkel angle, som kan være mellem +PI og -PI (+/- 180 grader).&lt;br /&gt;
&lt;br /&gt;
Begge bolde skal bevæge sig hurtigere efter de er delt, så spillet gradvist bliver sværere, derfor ganges hastigheden med 1,5.&lt;br /&gt;
&lt;br /&gt;
Den oprindelige bold får nu en ny retning, ved at udregne x- og y-hastigheden ud fra den nye hastighed og vinklen plus 30 grader.&lt;br /&gt;
&lt;br /&gt;
Til sidst oprettes en ny bold med samme position som den oprindelige og en x- og y-hastighed udregnet fra den oprindelige bolds hastighed og vinklen minus 30 grader. Denne bold returneres fra metoden.&lt;br /&gt;
==Referencer== &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt; &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Programmering}}&lt;br /&gt;
&lt;br /&gt;
[[Kategori:Programmering teknik]]&lt;/div&gt;</summary>
		<author><name>Bar</name></author>
	</entry>
	<entry>
		<id>https://www.htxarduino.dk/index.php?title=Programmering_med_ChatGPT&amp;diff=5392</id>
		<title>Programmering med ChatGPT</title>
		<link rel="alternate" type="text/html" href="https://www.htxarduino.dk/index.php?title=Programmering_med_ChatGPT&amp;diff=5392"/>
		<updated>2024-03-16T17:14:21Z</updated>

		<summary type="html">&lt;p&gt;Bar: /* Referencer */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Det er ikke så svært at få ChatGPT&amp;lt;ref&amp;gt;[https://chat.openai.com/auth/login ChatGPT Login] - Indgangen til ChatGPT&amp;lt;/ref&amp;gt; til at lave kode, der skal man blot beskrive hvad man gerne vil have programmet til at gøre, og så kopiere den kode, der kommer ud af det - det giver tit ret gode resultater.&lt;br /&gt;
&lt;br /&gt;
Problemet med at anvende ChatGPT i forbindelse med skoleprojekter er, at man har forståelsen med i det, og at man ikke kan blive anklaget for plagiat.&lt;br /&gt;
&lt;br /&gt;
==Hvad må man ikke i en skoleprojekt==&lt;br /&gt;
*Man må ikke kopiere kode, som man ikke selv har skrevet, til et programmeringsprodukt uden at man angiver en kilde. Det er uanset hvor koden stammer fra, også selvom man har brugt ChatGPT til at &amp;quot;udvikle&amp;quot; koden.&lt;br /&gt;
*Man må ikke aflevere et produkt hvor de primære dele af koden er kopieret, heller ikke selvom man kildehenviser.&lt;br /&gt;
*Man må ikke få ChatGPT til at dokumentere sin kode, ved at man kopierer ChatGPT&#039;s beskrivelse ind i sin dokumentation af koden.&lt;br /&gt;
&lt;br /&gt;
De beskrevne eksempler er at betragte som plagiat, og vil blive håndteret efter skolens ordensregler, hvilket i værste fald kan ende med at et fag annulleres eller man bliver bortvist fra uddannelsen.&lt;br /&gt;
==Hvad er tilladt med ChatGPT==&lt;br /&gt;
På samme måde som man må anvende kilder fra internettet, så må man i programmerings-faget i gymnasiet anvende ChatGPT i udviklingen af kode til et programmeringsprodukt. Dette er blevet tilladt via en revidering af vejledningen til faget&amp;lt;ref&amp;gt;[https://www.uvm.dk/-/media/filer/uvm/udd/gym/pdf23/aug/vejledninger/valgfag/230807-programmering-c--valgfag.pdf Vejledning] til Valgfaget Programmering C&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
I vejledningen står der som følger:&lt;br /&gt;
&lt;br /&gt;
: &#039;&#039;&amp;quot;brug af internettet er tilladt som fagligt hjælpemiddel ved de mundtlige prøver, inkluderer de tilladte hjælpemidler anvendelsen af chatbots og lignende på en måde, som afspejler, hvordan man arbejder i den daglige undervisning. Dette kunne fx være brug af ChatGPT til at debugge kode.&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Det skal altså afspejle den normale brug, som man også har ved at bruge internettet. Som angivet under hvad man ikke må, så er den normale brug, at man anvender information til at lære et programmere, men at man ikke tager så meget af sit produkt fra nettet, så man ikke har en forståelse af hvordan produktet er sammensat.&lt;br /&gt;
&lt;br /&gt;
Videre i vejledningen står der:&lt;br /&gt;
&lt;br /&gt;
: &#039;&#039;&amp;quot;I forhold til denne type hjælpemidler er det vigtigt at være opmærksom på, at den tilladte anvendelse er betinget af, at hjælpemidlerne kun benyttes i et omfang, hvor prøvebesvarelsen er selvstændig og udelukkende elevens egen.&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Igen understreges at det der afleveres skal være elevens selvstændigt udviklede produkt og dokumentation, hvor man på normal vis anvender internettet som et værktøj til at bibringe forståelse.&lt;br /&gt;
&lt;br /&gt;
==Problemet med ChatGPT==&lt;br /&gt;
Ligesom man ikke kan kilde-henvise til &amp;quot;google&amp;quot;, for at angive at man har fundet informationer på nettet, så kan man heller ikke kildehenvise til ChatGPT direkte som en kilde.&lt;br /&gt;
&lt;br /&gt;
Når man finder informationer med google&#039;, så skal man angive hvor på nettet man har fundet dem med så præcis en kildehenvisning, at man kan se den information der er blevet anvendt.&lt;br /&gt;
&lt;br /&gt;
Denne type henvisning kan man ikke lave i forhold til ChatGPT, da sprogmodellen der ligger bag ChatGPT konstant udvikler sig, samt at de svar sprogmodellen giver her et randomiseret element indbygget, som er med til at give bedre svar&amp;lt;ref&amp;gt;[https://www.it-vest.dk/arrangementer/sig-webinar-14-marts-2024-kunstig-intelligens-og-chatgpt-hvordan-virker-det-og-skal-vi-bare-opgive-undervisning-og-eksamen Webinar om kunstig intelligens]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Her er man altså nødt til at tage andre metoder i brug, for at kunne dokumentere at man har udviklet sit produkt ordentligt og redeligt.&lt;br /&gt;
==Kildehenvisninger i dokumentation==&lt;br /&gt;
Der kan være forskellige standarder for hvordan man kildehenviser i forskellige uddannelser, dette er skrevet med udgangspunkt i at man anvender Word bibliografi-værktøj og her vist med en Harvard-lignende standard&amp;lt;ref&amp;gt;[https://holstebro-htx.dk/index.php/Word_Kildeliste Kildelister] anvendt i Microsoft Word&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Normal Internet-kilde til kode===&lt;br /&gt;
I dette eksempel er der angivet hvordan man ville dokumentere at man har anvendt kode fra et bibliotek til noget hardware på en [[Arduino]]. I det tænkte eksempel er det en 4 kanals AD-konverter&amp;lt;ref&amp;gt;[https://arduinotech.dk/shop/ads1115-module-4-channel-16-bit-i2c-adc-with-pro-gain-amplifier 4 kanals AD-konverter] fra ArduinoTech&amp;lt;/ref&amp;gt;, der er købt som modul.&lt;br /&gt;
&lt;br /&gt;
For at kunne anvende modulet i koden skal der kommunikeres med modulet på en måde, som er angivet i beskrivelsen af modulet - det er dog ikke nødvendigt at sætte sig ind i den grundlæggende kommunikation, hvis man blot ønsker at få værdier ind i sin software. Som en dokumentation for hvordan man anvender biblioteket kan man skrive følgende:&lt;br /&gt;
&lt;br /&gt;
====Eksempel på dokumentation====&lt;br /&gt;
Til at hente værdierne fra den 4 kanals AD-konverter anvendes et bibliotek fundet på GitHub (Singh, 2018) som kan indlæse de analoge spændinger.&lt;br /&gt;
Til at sætte AD-konverteren rigtigt op, til at kunne læse 4 spændinger, så anvendes eksemplet ”ADS1115_SingleEnded.ino” og i setup skrives følgende kode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
    ads.getAddr_ADS1115(ADS1115_DEFAULT_ADDRESS);   // 0x48, 1001 000 (ADDR = GND)&lt;br /&gt;
    ads.setGain(GAIN_TWO);          // 2x gain   +/- 2.048V  1 bit = 0.0625mV (default)&lt;br /&gt;
    ads.setMode(MODE_CONTIN);       // Continuous conversion mode&lt;br /&gt;
    ads.setRate(RATE_128);          // 128SPS (default)&lt;br /&gt;
    ads.setOSMode(OSMODE_SINGLE);   // Set to start a single-conversion&lt;br /&gt;
    ads.begin();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
I [[loop()]] testes i første omgang, om det kan lade sig gøre at læse de 4 kanaler. Dette gøres ved at afvikle følgende testkode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
    address = ads.ads_i2cAddress;&lt;br /&gt;
    Wire.beginTransmission(address);&lt;br /&gt;
    error = Wire.endTransmission();&lt;br /&gt;
    if (error == 0)&lt;br /&gt;
    {&lt;br /&gt;
        int16_t adc0, adc1, adc2, adc3;&lt;br /&gt;
&lt;br /&gt;
        adc0 = ads.Measure_SingleEnded(0);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 1: &amp;quot;);&lt;br /&gt;
        Serial.println(adc0);&lt;br /&gt;
        adc1 = ads.Measure_SingleEnded(1);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 2: &amp;quot;);&lt;br /&gt;
        Serial.println(adc1);&lt;br /&gt;
        adc2 = ads.Measure_SingleEnded(2);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 3: &amp;quot;);&lt;br /&gt;
        Serial.println(adc2);&lt;br /&gt;
        adc3 = ads.Measure_SingleEnded(3);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 4: &amp;quot;);&lt;br /&gt;
        Serial.println(adc3);&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Denne test giver det ønskede resultat.&lt;br /&gt;
&lt;br /&gt;
Ud fra denne beskrivelse viser man, at man tager andres kode, og anvender ind i sit eget projekt, og man angiver præcist i sin beskrivelse hvad man har taget fra andres kode.&lt;br /&gt;
&lt;br /&gt;
I kildelisten vil kilden optræde på følgende måde:&lt;br /&gt;
&lt;br /&gt;
Singh, Y., 2018. Arduino Library ADS1115 16 bit 4 channel ADC. [Online] &amp;lt;br /&amp;gt;&lt;br /&gt;
Available at: https://github.com/ncdcommunity/Arduino_Library_ADS1115_16Bit_4Channel_ADC&amp;lt;br /&amp;gt;&lt;br /&gt;
[Senest hentet eller vist den 15 marts 2024].&lt;br /&gt;
&lt;br /&gt;
===ChatGPT som kilde til kode===&lt;br /&gt;
Hvis man forstår at prompte fornuftigt, så er ChatGPT faktisk ret god til at foreslå kode, der kan anvendes, men ligesom det er plagiat hvis man kopierer fra nettet, så er det plagiat, hvis man lader ChatGPT skrive store dele af ens program for sig.&lt;br /&gt;
&lt;br /&gt;
Som det er formuleret i vejledningen til både programmering C og B, så kan man anvende ChatGPT til hjælp i fejlfinding af kode. For at kunne kildehenvise korrekt til hjælp med fejlfinding, så skal man angive hvad man har promptet til ChatGPT og hvad den har svaret - det kan placeres i bilag.&lt;br /&gt;
&lt;br /&gt;
En anden ting, som også er OK at få hjælp med er, at komme i gang med programmet - det er denne problematik der her gives et eksempel på. I eksemplet beskrives hvad man skal skrive i sin dokumentation, når man har anvendt denne hjælp, og der er forslag til hvordan man kommer videre i projektet.&lt;br /&gt;
&lt;br /&gt;
Konkret er det starten på udviklingen af et lille spil med bolde i et vindue, udviklet i Processing- der tages udgangspunkt i.&lt;br /&gt;
&lt;br /&gt;
====Metodeafsnit med omtale af ChatGPT====&lt;br /&gt;
Når man anvender CharGPT, så skal man dokumentere hvordan man har gjort det, og hvilke overvejelser der ligger bag det. Det betegnes i rapportskrivning som et metodeafsnit. Det kunne i dette eksempel lyde:&lt;br /&gt;
&lt;br /&gt;
For at få en fornuftig start på programkoden er der brugt ChatGPT til at få rammerne på koden etableret, og til at få et system, så der kan optræde flere bolde i programvinduet. Det er ChatGPT 3.5 (OpenAI, 2023) der er anvendt til denne hjælp. Til programstarten blev der promptet efter at få et programvindue på 800x600 hvor en bold bevæger sig rundt. Den foreslåede kode blev kopieret ind i processings IDE (Processing, 2024) og testet – den opførte sig som forventet.&lt;br /&gt;
&lt;br /&gt;
Derefter blev der promptet efter at få den bold der bevægede sig til at dele sig op i to, når man klikker på den med musen. Dette resulterede i en væsentligt anderledes kode, som igen blev kopieret ind i processing og testet, og igen med et acceptabelt resultat. Dialogen med ChatGPT (OpenAI, 2023) og herunder de to koder, kan ses i bilag 1.&lt;br /&gt;
&lt;br /&gt;
Herefter er resten af koden udviklet på traditionel vis, hvor første trin var at dokumentere princippet i den foreslåede kode, specielt den Ball klasse der blev introduceret for at kunne arbejde med flere bolde i vinduet.&lt;br /&gt;
&lt;br /&gt;
Det nævnte bilag 1 [[media:ChatGPT-dialog-1.pdf|kan ses i denne PDF]].&lt;br /&gt;
&lt;br /&gt;
====Dokumentation af koden udviklet af ChatGPT====&lt;br /&gt;
Da der skulle kunne dannes nye bolde så oprettes der en klasse, som ChatGPT skriver det i dialogen i Bilag 1:&lt;br /&gt;
&lt;br /&gt;
: &#039;&#039;&amp;quot;Dette kodeeksempel opretter en klasse kaldet Ball, som repræsenterer boldobjekterne. Når musen klikkes, kontrolleres det, om musens position er inden for en bold. Hvis det er tilfældet, oprettes to nye boldobjekter, der bevæger sig i forskellige retninger, og den originale bold fjernes fra arrayet.&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Ved at teste koden kan man se at det ikke er det helt rigtige den formulerer - der oprettes godt nok to nye bold-objekter, men det er ikke den oprindelige bold der fjernes, det er den ene af de ny-oprettede bolde. Det kan ses ved at de to bolde kommer i samme position, og den ene fortsætter i samme retning (den oprindelige), mens den ny-oprettede går i en tilfældig retning. Dette rettes til senere i dokumentationen under &amp;quot;oprettelse af ny bold&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
For at have en god struktur i koden, så placeres klassen Ball i en fil for sig kaldet Ball. Denne fil starter med at definere koden som en klasse med linjen:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
class Ball {&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dernæst defineres klassens egenskaber, der er boldens position og hastighed samt en fast diameter. Ud over det er der en x- og y-retning defineret. Den anvendes til at sige om bolden bevæger sig i en positiv eller negativ retning, så de skifter mellem +1 og -1, når kanterne rammes.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  float x, y;&lt;br /&gt;
  float xspeed, yspeed;&lt;br /&gt;
  int diameter = 30;&lt;br /&gt;
  int xdirection = 1;&lt;br /&gt;
  int ydirection = 1;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der defineres to forskellige constructors til bolden. Den første anvendes til at danne den første bold med, hvor position og hastighed sættes tilfældigt.&lt;br /&gt;
&lt;br /&gt;
Her forudses et problem at der kan komme et randfænomen, hvis bolden dannes, så den ligger med noget uden for skærmen. Da det er tilfældigt; så er det sjældent problemet opstår. For at fremprovokere det oftere er det testet med en diameter på 200, hvor det kunne ses at bolden bliver &amp;quot;hængende&amp;quot; i kanten.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  Ball() {&lt;br /&gt;
    x = random(width);&lt;br /&gt;
    y = random(height);&lt;br /&gt;
    xspeed = random(0.5, 2);&lt;br /&gt;
    yspeed = random(0.5, 2);&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Dette rettes ved at omskrive de constructor til følgende kode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  Ball() {&lt;br /&gt;
    x = random(diameter / 2, width - diameter / 2);&lt;br /&gt;
    y = random(diameter / 2, height - diameter / 2);&lt;br /&gt;
    xspeed = random(0.5, 2);&lt;br /&gt;
    yspeed = random(0.5, 2);&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Den anden constructor tager fire parametre, der er positionen og hastigheden. Denne constructor anvendes, når der skal dannes nye bolde, hvor koden netop skal starte den nye bold i den oprindelige bolds position, og med en ny retning.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  Ball(float x, float y, float xspeed, float yspeed) {&lt;br /&gt;
    this.x = x;&lt;br /&gt;
    this.y = y;&lt;br /&gt;
    this.xspeed = xspeed;&lt;br /&gt;
    this.yspeed = yspeed;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ud over disse standard ting til oprettelsen af objekter, så er der 3 metoder i klassen. Den første er en move() metode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  void move() {&lt;br /&gt;
    x = x + (xspeed * xdirection);&lt;br /&gt;
    y = y + (yspeed * ydirection);&lt;br /&gt;
&lt;br /&gt;
    if ((x + diameter/2 &amp;gt;= width) || (x - diameter/2 &amp;lt;= 0)) {&lt;br /&gt;
      xdirection *= -1;&lt;br /&gt;
    }&lt;br /&gt;
    if ((y + diameter/2 &amp;gt;= height) || (y - diameter/2 &amp;lt;= 0)) {&lt;br /&gt;
      ydirection *= -1;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Måden metoden virker på er at den lægger hastigheden til boldens position (både x og y), og hvis boldens position (både i x og y) er kommet uden for rammen, så ændres retningen for enten x eller y.&lt;br /&gt;
&lt;br /&gt;
For at kunne vise bolden er der en display() metode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  void display() {&lt;br /&gt;
    ellipse(x, y, diameter, diameter);&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Den sidste metode hedder contains(), og den tager en position som parameter til metoden. Der undersøges så om den position ligger inden for bolden ved at se om afstanden mellem boldens center og den testede position er mindre end den halve diameter. Hvis den er inden for bolden, så returneres true, ellers returneres false:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  boolean contains(float x, float y) {&lt;br /&gt;
    float d = dist(x, y, this.x, this.y);&lt;br /&gt;
    if (d &amp;lt; diameter/2) {&lt;br /&gt;
      return true;&lt;br /&gt;
    } else {&lt;br /&gt;
      return false;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Oprettelse af ny bold====&lt;br /&gt;
I den oprindelige kode undersøges om der er klikket på en bold, ved at alle bolde løbes igennem i mousePressed() funktionen, og med metoden contains undersøges om der er klikket på en bold. Denne måde at undersøge alle bolde på beholdes.&lt;br /&gt;
&lt;br /&gt;
Som omtalt er det ikke den smarteste måde til at dele bolden op i to, der anvendes. Som det ses i koden herunder, så appendes der to nye bolde på med den oprindelige bolds x- og y-position på samt tilfældige x- og y-hastigheder. Disse to bolde lægges i slutningen af arrayet. Derefter anvendes shorten&amp;lt;ref&amp;gt;[https://processing.org/reference/shorten_.html Processings shorten metode til arrays]&amp;lt;/ref&amp;gt; til at fjerne et element, men da det element der fjernes er det sidste element i arrayet, så fjernes der bare den sidst oprettede bold.&lt;br /&gt;
&lt;br /&gt;
Hvis man var tilfreds med den opførsel, så kunne man blot fjerne kodelinjen med den anden append og kodelinjen med shorten. Så ville man have samme funktion.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
    if (balls[i].contains(mouseX, mouseY)) {&lt;br /&gt;
      balls = (Ball[]) append(balls, new Ball(balls[i].x, balls[i].y, random(-5, 5), random(-5, 5)));&lt;br /&gt;
      balls = (Ball[]) append(balls, new Ball(balls[i].x, balls[i].y, random(-5, 5), random(-5, 5)));&lt;br /&gt;
      balls = (Ball[]) shorten(balls);&lt;br /&gt;
      break;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Den nye bold der oprettes får bare en tilfældig retning, og den oprindelige bold fortsætter bare i den retning den var på vej i. Det er ikke den opførsel der ønskes i spillet. Der ønskes i stedet at det ser ud som om bolden &amp;quot;splittes op&amp;quot; i 2 bolde, og den opførsel laves ved at lade den oprindelige bold ændre 30 grader til den ene side, og den nye bold får 30 grader til den anden side.&lt;br /&gt;
&lt;br /&gt;
For at gøre dette, så oprettes der en metode multiply() i klassen Ball. Denne metode returnerer en ny bold af typen Ball, så nu kan koden i museklikket skrives som følger:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
    if (balls[i].contains(mouseX, mouseY)) {&lt;br /&gt;
      balls = (Ball[]) append(balls, balls[i].multiply());&lt;br /&gt;
      break;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Som det kan ses, så appendes der en ny bold ind i balls-arrayet, ud fra metoden multiply().&lt;br /&gt;
&lt;br /&gt;
Metoden multiply() oprettes inde i klassen med følgende kode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  Ball multiply() {&lt;br /&gt;
    xspeed *= xdirection;&lt;br /&gt;
    yspeed *= ydirection;&lt;br /&gt;
    xdirection = 1;&lt;br /&gt;
    ydirection = 1;&lt;br /&gt;
    float speed = dist(0, 0, xspeed, yspeed);&lt;br /&gt;
    float angle = acos(xspeed / speed);&lt;br /&gt;
    if (yspeed &amp;lt; 0) angle = 0.0 - angle;&lt;br /&gt;
    speed *= 1.5;&lt;br /&gt;
    xspeed = speed * cos(angle + PI / 6);&lt;br /&gt;
    yspeed = speed * sin(angle + PI / 6);&lt;br /&gt;
    Ball b = new Ball(x, y, speed * cos(angle - PI / 6), speed * sin(angle - PI / 6));&lt;br /&gt;
    return b;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Først regnes retningen over i xspeed og yspeed, så de kan være både positive og negative. På den måde indeholder de to variabler retningen.&lt;br /&gt;
&lt;br /&gt;
Dernæst omregnes x- og y-hastigheden til en samlet hastighed speed og en vinkel angle, som kan være mellem +PI og -PI (+/- 180 grader).&lt;br /&gt;
&lt;br /&gt;
Begge bolde skal bevæge sig hurtigere efter de er delt, så spillet gradvist bliver sværere, derfor ganges hastigheden med 1,5.&lt;br /&gt;
&lt;br /&gt;
Den oprindelige bold får nu en ny retning, ved at udregne x- og y-hastigheden ud fra den nye hastighed og vinklen plus 30 grader.&lt;br /&gt;
&lt;br /&gt;
Til sidst oprettes en ny bold med samme position som den oprindelige og en x- og y-hastighed udregnet fra den oprindelige bolds hastighed og vinklen minus 30 grader. Denne bold returneres fra metoden.&lt;br /&gt;
==Referencer== &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt; &lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Programmering}}&lt;br /&gt;
&lt;br /&gt;
[[Kategori:Programmering teknik]]&lt;/div&gt;</summary>
		<author><name>Bar</name></author>
	</entry>
	<entry>
		<id>https://www.htxarduino.dk/index.php?title=Skabelon:Programmering&amp;diff=5391</id>
		<title>Skabelon:Programmering</title>
		<link rel="alternate" type="text/html" href="https://www.htxarduino.dk/index.php?title=Skabelon:Programmering&amp;diff=5391"/>
		<updated>2024-03-16T17:13:53Z</updated>

		<summary type="html">&lt;p&gt;Bar: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;{| class=&amp;quot;oversigt&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
&amp;lt;th colspan=&amp;quot;2&amp;quot;&amp;gt; [[:Kategori:Programmering|Programmering]]&amp;lt;/th&amp;gt;&lt;br /&gt;
|-&lt;br /&gt;
|id=&amp;quot;emne&amp;quot;| [[:Kategori:Programmeringsbegreber|Programmeringsbegreber]] || [[Initialisering]] - [[Sekvens]] - [[Algoritme]] - [[Hexadecimal]] - [[Det Binære Talsystem]] - [[HEX-fil]] - [[ASCII]] - [[Interrupt]] - [[Events]] - [[Styresystem]] - [[Autocomplete]] - [[Selvstudie Programmering]] - [[Hour Of Code]] - [[Stepwise Improvement]] - [[Syntaks]] - [[Prog-links]] - [[:Kategori:Microcontroller|Microcontroller]] - [[Programmering_med_ChatGPT|ChatGPT]]&lt;br /&gt;
|-&lt;br /&gt;
|id=&amp;quot;emne&amp;quot;| [[:Kategori:Grundlæggende C|Grundlæggende C]] || [[C float]] - [[C double]] - [[C-løkker]] - [[Datatyper]] - [[Konstanter]] - [[Regnearter]] - [[Funktioner]] - [[Return]] - [[Returværdi]] - [[Rekursion]] - [[Semikolon]]&lt;br /&gt;
|-&lt;br /&gt;
|id=&amp;quot;emne&amp;quot;| [[:Kategori:Variabel-typer|Variabel Typer]] || [[Datatyper#boolean|boolean]] - [[Datatyper#byte|byte]] - [[Datatyper#int|int]] - [[Datatyper#unsigned int|unsigned int]] - [[Datatyper#word|word]] - [[Datatyper#long|long]] - [[Datatyper#unsigned long|unsigned long]] - [[Datatyper#short|short]] - [[Datatyper#float|float]] - [[Datatyper#double|double]] - [[Datatyper#char|char]] - [[Datatyper#unsigned char|unsigned char]] - [[Datatyper#string|string - char array]] - [[Datatyper#String_2|String - object]] - [[Array]] - [[2-dimensionelt Array]] - [[Datatyper#void|void]]&lt;br /&gt;
|-&lt;br /&gt;
|id=&amp;quot;emne&amp;quot;| [[:Kategori:Program-klassikere|Program-klassikere]] || [[Polling]] - [[State-machine]] - [[Trykknap]] - [[Forkant]] - [[Bagkant]] - [[Prel]] &lt;br /&gt;
|-&lt;br /&gt;
|id=&amp;quot;emne&amp;quot;| [[:Kategori:Arduino|Arduino]] || [[:Kategori:Arduino til Programmering|Arduino til Programmering]] - [[:Kategori:C til Arduino|C til Arduino]] - [[Programmering Shield]] - [[Arduino PC-software]] - [[Arduino Udviklingsmiljø]] - [[Arduino Pin Library]] - [[:Kategori:Funktion|Funktion]] - [[:Kategori:Arduino Seriel|Arduino Seriel]] - [[:Kategori:Arduino String|Arduino String]] - [[Arduino String Split]] - [[Arduino StateChangeDetection]] - [[setup()]] - [[loop()]] - [[Compilerdirektiver]] - [[Asynkron kommunikation]] - [[millis()]] - [[micros()]] - [[:Kategori:Scratch for Arduino|Scratch for Arduino]] - [[Send fra Arduino til Excel]] - [[]] - [[]]&lt;br /&gt;
|-&lt;br /&gt;
|id=&amp;quot;emne&amp;quot;| [[:Kategori:Processing|Processing]] || [[:Kategori:Grafik i Processing‎|Grafik i Processing‎]] - [[:Kategori:Keyboard i Processing|Keyboard i Processing]] - [[:Kategori:Mus i Processing‎|Mus i Processing‎]] - [[:Kategori:Tid i Processing‎|Tid i Processing‎]] - [[Draw()]] - [[Setup()]] - [[Tal Input til Processing]] - [[Syntaksfarvning]] - [[Kommunikation fra Arduino til Processing]] - [[Kommunikation fra Processing til Arduino]]&lt;br /&gt;
|-&lt;br /&gt;
|id=&amp;quot;emne&amp;quot;| [[:Kategori:javascript|javaScript]] || [[:kategori:Javascript input‎|Javascript input‎]] - [[:kategori:Javascript output‎|Javascript output‎]] - [[:kategori:Javascript strukturer‎|Javascript strukturer‎]] - [[:kategori:Javascript syntaks‎|Javascript syntaks‎]] - [[Tid i javaScript]] - [[Objekt‎]] - [[AJAX]]&lt;br /&gt;
|-&lt;br /&gt;
|id=&amp;quot;emne&amp;quot;| [[:Kategori:Server|Serverprogrammering]] || [[PHP]] - [[MySQL]] - [[Task Scheduler]] - [[WeMOS]]&lt;br /&gt;
|-&lt;br /&gt;
|id=&amp;quot;emne&amp;quot;| [[:Kategori:PIC|PIC]] || [[JAL]] - [[]]&lt;br /&gt;
|-&lt;br /&gt;
|id=&amp;quot;emne&amp;quot;| [[:Kategori:Scratch for Arduino|Scratch for Arduino]] || [[S4A Installation]] - [[S4A programmering]] - [[S4A undervisningsforløb]] - [[S4A begrænsninger]]&lt;br /&gt;
|-&lt;br /&gt;
|id=&amp;quot;emne&amp;quot;| [[:Kategori:Dokumentationsformer|Program Dokumentation]] || [[Algoritme]] - [[Flowchart]] - [[Pseudokode]] - [[Datastruktur]] - [[Dataabstraktion]] - [[Pulsplaner]] - [[Program-kommentar]] - [[Teori]] - [[Test]] - [[UML]]&lt;br /&gt;
|}&lt;/div&gt;</summary>
		<author><name>Bar</name></author>
	</entry>
	<entry>
		<id>https://www.htxarduino.dk/index.php?title=Programmering_med_ChatGPT&amp;diff=5390</id>
		<title>Programmering med ChatGPT</title>
		<link rel="alternate" type="text/html" href="https://www.htxarduino.dk/index.php?title=Programmering_med_ChatGPT&amp;diff=5390"/>
		<updated>2024-03-16T17:01:00Z</updated>

		<summary type="html">&lt;p&gt;Bar: /* Referencer */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Det er ikke så svært at få ChatGPT&amp;lt;ref&amp;gt;[https://chat.openai.com/auth/login ChatGPT Login] - Indgangen til ChatGPT&amp;lt;/ref&amp;gt; til at lave kode, der skal man blot beskrive hvad man gerne vil have programmet til at gøre, og så kopiere den kode, der kommer ud af det - det giver tit ret gode resultater.&lt;br /&gt;
&lt;br /&gt;
Problemet med at anvende ChatGPT i forbindelse med skoleprojekter er, at man har forståelsen med i det, og at man ikke kan blive anklaget for plagiat.&lt;br /&gt;
&lt;br /&gt;
==Hvad må man ikke i en skoleprojekt==&lt;br /&gt;
*Man må ikke kopiere kode, som man ikke selv har skrevet, til et programmeringsprodukt uden at man angiver en kilde. Det er uanset hvor koden stammer fra, også selvom man har brugt ChatGPT til at &amp;quot;udvikle&amp;quot; koden.&lt;br /&gt;
*Man må ikke aflevere et produkt hvor de primære dele af koden er kopieret, heller ikke selvom man kildehenviser.&lt;br /&gt;
*Man må ikke få ChatGPT til at dokumentere sin kode, ved at man kopierer ChatGPT&#039;s beskrivelse ind i sin dokumentation af koden.&lt;br /&gt;
&lt;br /&gt;
De beskrevne eksempler er at betragte som plagiat, og vil blive håndteret efter skolens ordensregler, hvilket i værste fald kan ende med at et fag annulleres eller man bliver bortvist fra uddannelsen.&lt;br /&gt;
==Hvad er tilladt med ChatGPT==&lt;br /&gt;
På samme måde som man må anvende kilder fra internettet, så må man i programmerings-faget i gymnasiet anvende ChatGPT i udviklingen af kode til et programmeringsprodukt. Dette er blevet tilladt via en revidering af vejledningen til faget&amp;lt;ref&amp;gt;[https://www.uvm.dk/-/media/filer/uvm/udd/gym/pdf23/aug/vejledninger/valgfag/230807-programmering-c--valgfag.pdf Vejledning] til Valgfaget Programmering C&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
I vejledningen står der som følger:&lt;br /&gt;
&lt;br /&gt;
: &#039;&#039;&amp;quot;brug af internettet er tilladt som fagligt hjælpemiddel ved de mundtlige prøver, inkluderer de tilladte hjælpemidler anvendelsen af chatbots og lignende på en måde, som afspejler, hvordan man arbejder i den daglige undervisning. Dette kunne fx være brug af ChatGPT til at debugge kode.&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Det skal altså afspejle den normale brug, som man også har ved at bruge internettet. Som angivet under hvad man ikke må, så er den normale brug, at man anvender information til at lære et programmere, men at man ikke tager så meget af sit produkt fra nettet, så man ikke har en forståelse af hvordan produktet er sammensat.&lt;br /&gt;
&lt;br /&gt;
Videre i vejledningen står der:&lt;br /&gt;
&lt;br /&gt;
: &#039;&#039;&amp;quot;I forhold til denne type hjælpemidler er det vigtigt at være opmærksom på, at den tilladte anvendelse er betinget af, at hjælpemidlerne kun benyttes i et omfang, hvor prøvebesvarelsen er selvstændig og udelukkende elevens egen.&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Igen understreges at det der afleveres skal være elevens selvstændigt udviklede produkt og dokumentation, hvor man på normal vis anvender internettet som et værktøj til at bibringe forståelse.&lt;br /&gt;
&lt;br /&gt;
==Problemet med ChatGPT==&lt;br /&gt;
Ligesom man ikke kan kilde-henvise til &amp;quot;google&amp;quot;, for at angive at man har fundet informationer på nettet, så kan man heller ikke kildehenvise til ChatGPT direkte som en kilde.&lt;br /&gt;
&lt;br /&gt;
Når man finder informationer med google&#039;, så skal man angive hvor på nettet man har fundet dem med så præcis en kildehenvisning, at man kan se den information der er blevet anvendt.&lt;br /&gt;
&lt;br /&gt;
Denne type henvisning kan man ikke lave i forhold til ChatGPT, da sprogmodellen der ligger bag ChatGPT konstant udvikler sig, samt at de svar sprogmodellen giver her et randomiseret element indbygget, som er med til at give bedre svar&amp;lt;ref&amp;gt;[https://www.it-vest.dk/arrangementer/sig-webinar-14-marts-2024-kunstig-intelligens-og-chatgpt-hvordan-virker-det-og-skal-vi-bare-opgive-undervisning-og-eksamen Webinar om kunstig intelligens]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Her er man altså nødt til at tage andre metoder i brug, for at kunne dokumentere at man har udviklet sit produkt ordentligt og redeligt.&lt;br /&gt;
==Kildehenvisninger i dokumentation==&lt;br /&gt;
Der kan være forskellige standarder for hvordan man kildehenviser i forskellige uddannelser, dette er skrevet med udgangspunkt i at man anvender Word bibliografi-værktøj og her vist med en Harvard-lignende standard&amp;lt;ref&amp;gt;[https://holstebro-htx.dk/index.php/Word_Kildeliste Kildelister] anvendt i Microsoft Word&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Normal Internet-kilde til kode===&lt;br /&gt;
I dette eksempel er der angivet hvordan man ville dokumentere at man har anvendt kode fra et bibliotek til noget hardware på en [[Arduino]]. I det tænkte eksempel er det en 4 kanals AD-konverter&amp;lt;ref&amp;gt;[https://arduinotech.dk/shop/ads1115-module-4-channel-16-bit-i2c-adc-with-pro-gain-amplifier 4 kanals AD-konverter] fra ArduinoTech&amp;lt;/ref&amp;gt;, der er købt som modul.&lt;br /&gt;
&lt;br /&gt;
For at kunne anvende modulet i koden skal der kommunikeres med modulet på en måde, som er angivet i beskrivelsen af modulet - det er dog ikke nødvendigt at sætte sig ind i den grundlæggende kommunikation, hvis man blot ønsker at få værdier ind i sin software. Som en dokumentation for hvordan man anvender biblioteket kan man skrive følgende:&lt;br /&gt;
&lt;br /&gt;
====Eksempel på dokumentation====&lt;br /&gt;
Til at hente værdierne fra den 4 kanals AD-konverter anvendes et bibliotek fundet på GitHub (Singh, 2018) som kan indlæse de analoge spændinger.&lt;br /&gt;
Til at sætte AD-konverteren rigtigt op, til at kunne læse 4 spændinger, så anvendes eksemplet ”ADS1115_SingleEnded.ino” og i setup skrives følgende kode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
    ads.getAddr_ADS1115(ADS1115_DEFAULT_ADDRESS);   // 0x48, 1001 000 (ADDR = GND)&lt;br /&gt;
    ads.setGain(GAIN_TWO);          // 2x gain   +/- 2.048V  1 bit = 0.0625mV (default)&lt;br /&gt;
    ads.setMode(MODE_CONTIN);       // Continuous conversion mode&lt;br /&gt;
    ads.setRate(RATE_128);          // 128SPS (default)&lt;br /&gt;
    ads.setOSMode(OSMODE_SINGLE);   // Set to start a single-conversion&lt;br /&gt;
    ads.begin();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
I [[loop()]] testes i første omgang, om det kan lade sig gøre at læse de 4 kanaler. Dette gøres ved at afvikle følgende testkode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
    address = ads.ads_i2cAddress;&lt;br /&gt;
    Wire.beginTransmission(address);&lt;br /&gt;
    error = Wire.endTransmission();&lt;br /&gt;
    if (error == 0)&lt;br /&gt;
    {&lt;br /&gt;
        int16_t adc0, adc1, adc2, adc3;&lt;br /&gt;
&lt;br /&gt;
        adc0 = ads.Measure_SingleEnded(0);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 1: &amp;quot;);&lt;br /&gt;
        Serial.println(adc0);&lt;br /&gt;
        adc1 = ads.Measure_SingleEnded(1);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 2: &amp;quot;);&lt;br /&gt;
        Serial.println(adc1);&lt;br /&gt;
        adc2 = ads.Measure_SingleEnded(2);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 3: &amp;quot;);&lt;br /&gt;
        Serial.println(adc2);&lt;br /&gt;
        adc3 = ads.Measure_SingleEnded(3);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 4: &amp;quot;);&lt;br /&gt;
        Serial.println(adc3);&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Denne test giver det ønskede resultat.&lt;br /&gt;
&lt;br /&gt;
Ud fra denne beskrivelse viser man, at man tager andres kode, og anvender ind i sit eget projekt, og man angiver præcist i sin beskrivelse hvad man har taget fra andres kode.&lt;br /&gt;
&lt;br /&gt;
I kildelisten vil kilden optræde på følgende måde:&lt;br /&gt;
&lt;br /&gt;
Singh, Y., 2018. Arduino Library ADS1115 16 bit 4 channel ADC. [Online] &amp;lt;br /&amp;gt;&lt;br /&gt;
Available at: https://github.com/ncdcommunity/Arduino_Library_ADS1115_16Bit_4Channel_ADC&amp;lt;br /&amp;gt;&lt;br /&gt;
[Senest hentet eller vist den 15 marts 2024].&lt;br /&gt;
&lt;br /&gt;
===ChatGPT som kilde til kode===&lt;br /&gt;
Hvis man forstår at prompte fornuftigt, så er ChatGPT faktisk ret god til at foreslå kode, der kan anvendes, men ligesom det er plagiat hvis man kopierer fra nettet, så er det plagiat, hvis man lader ChatGPT skrive store dele af ens program for sig.&lt;br /&gt;
&lt;br /&gt;
Som det er formuleret i vejledningen til både programmering C og B, så kan man anvende ChatGPT til hjælp i fejlfinding af kode. For at kunne kildehenvise korrekt til hjælp med fejlfinding, så skal man angive hvad man har promptet til ChatGPT og hvad den har svaret - det kan placeres i bilag.&lt;br /&gt;
&lt;br /&gt;
En anden ting, som også er OK at få hjælp med er, at komme i gang med programmet - det er denne problematik der her gives et eksempel på. I eksemplet beskrives hvad man skal skrive i sin dokumentation, når man har anvendt denne hjælp, og der er forslag til hvordan man kommer videre i projektet.&lt;br /&gt;
&lt;br /&gt;
Konkret er det starten på udviklingen af et lille spil med bolde i et vindue, udviklet i Processing- der tages udgangspunkt i.&lt;br /&gt;
&lt;br /&gt;
====Metodeafsnit med omtale af ChatGPT====&lt;br /&gt;
Når man anvender CharGPT, så skal man dokumentere hvordan man har gjort det, og hvilke overvejelser der ligger bag det. Det betegnes i rapportskrivning som et metodeafsnit. Det kunne i dette eksempel lyde:&lt;br /&gt;
&lt;br /&gt;
For at få en fornuftig start på programkoden er der brugt ChatGPT til at få rammerne på koden etableret, og til at få et system, så der kan optræde flere bolde i programvinduet. Det er ChatGPT 3.5 (OpenAI, 2023) der er anvendt til denne hjælp. Til programstarten blev der promptet efter at få et programvindue på 800x600 hvor en bold bevæger sig rundt. Den foreslåede kode blev kopieret ind i processings IDE (Processing, 2024) og testet – den opførte sig som forventet.&lt;br /&gt;
&lt;br /&gt;
Derefter blev der promptet efter at få den bold der bevægede sig til at dele sig op i to, når man klikker på den med musen. Dette resulterede i en væsentligt anderledes kode, som igen blev kopieret ind i processing og testet, og igen med et acceptabelt resultat. Dialogen med ChatGPT (OpenAI, 2023) og herunder de to koder, kan ses i bilag 1.&lt;br /&gt;
&lt;br /&gt;
Herefter er resten af koden udviklet på traditionel vis, hvor første trin var at dokumentere princippet i den foreslåede kode, specielt den Ball klasse der blev introduceret for at kunne arbejde med flere bolde i vinduet.&lt;br /&gt;
&lt;br /&gt;
Det nævnte bilag 1 [[media:ChatGPT-dialog-1.pdf|kan ses i denne PDF]].&lt;br /&gt;
&lt;br /&gt;
====Dokumentation af koden udviklet af ChatGPT====&lt;br /&gt;
Da der skulle kunne dannes nye bolde så oprettes der en klasse, som ChatGPT skriver det i dialogen i Bilag 1:&lt;br /&gt;
&lt;br /&gt;
: &#039;&#039;&amp;quot;Dette kodeeksempel opretter en klasse kaldet Ball, som repræsenterer boldobjekterne. Når musen klikkes, kontrolleres det, om musens position er inden for en bold. Hvis det er tilfældet, oprettes to nye boldobjekter, der bevæger sig i forskellige retninger, og den originale bold fjernes fra arrayet.&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Ved at teste koden kan man se at det ikke er det helt rigtige den formulerer - der oprettes godt nok to nye bold-objekter, men det er ikke den oprindelige bold der fjernes, det er den ene af de ny-oprettede bolde. Det kan ses ved at de to bolde kommer i samme position, og den ene fortsætter i samme retning (den oprindelige), mens den ny-oprettede går i en tilfældig retning. Dette rettes til senere i dokumentationen under &amp;quot;oprettelse af ny bold&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
For at have en god struktur i koden, så placeres klassen Ball i en fil for sig kaldet Ball. Denne fil starter med at definere koden som en klasse med linjen:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
class Ball {&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dernæst defineres klassens egenskaber, der er boldens position og hastighed samt en fast diameter. Ud over det er der en x- og y-retning defineret. Den anvendes til at sige om bolden bevæger sig i en positiv eller negativ retning, så de skifter mellem +1 og -1, når kanterne rammes.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  float x, y;&lt;br /&gt;
  float xspeed, yspeed;&lt;br /&gt;
  int diameter = 30;&lt;br /&gt;
  int xdirection = 1;&lt;br /&gt;
  int ydirection = 1;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der defineres to forskellige constructors til bolden. Den første anvendes til at danne den første bold med, hvor position og hastighed sættes tilfældigt.&lt;br /&gt;
&lt;br /&gt;
Her forudses et problem at der kan komme et randfænomen, hvis bolden dannes, så den ligger med noget uden for skærmen. Da det er tilfældigt; så er det sjældent problemet opstår. For at fremprovokere det oftere er det testet med en diameter på 200, hvor det kunne ses at bolden bliver &amp;quot;hængende&amp;quot; i kanten.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  Ball() {&lt;br /&gt;
    x = random(width);&lt;br /&gt;
    y = random(height);&lt;br /&gt;
    xspeed = random(0.5, 2);&lt;br /&gt;
    yspeed = random(0.5, 2);&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Dette rettes ved at omskrive de constructor til følgende kode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  Ball() {&lt;br /&gt;
    x = random(diameter / 2, width - diameter / 2);&lt;br /&gt;
    y = random(diameter / 2, height - diameter / 2);&lt;br /&gt;
    xspeed = random(0.5, 2);&lt;br /&gt;
    yspeed = random(0.5, 2);&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Den anden constructor tager fire parametre, der er positionen og hastigheden. Denne constructor anvendes, når der skal dannes nye bolde, hvor koden netop skal starte den nye bold i den oprindelige bolds position, og med en ny retning.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  Ball(float x, float y, float xspeed, float yspeed) {&lt;br /&gt;
    this.x = x;&lt;br /&gt;
    this.y = y;&lt;br /&gt;
    this.xspeed = xspeed;&lt;br /&gt;
    this.yspeed = yspeed;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ud over disse standard ting til oprettelsen af objekter, så er der 3 metoder i klassen. Den første er en move() metode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  void move() {&lt;br /&gt;
    x = x + (xspeed * xdirection);&lt;br /&gt;
    y = y + (yspeed * ydirection);&lt;br /&gt;
&lt;br /&gt;
    if ((x + diameter/2 &amp;gt;= width) || (x - diameter/2 &amp;lt;= 0)) {&lt;br /&gt;
      xdirection *= -1;&lt;br /&gt;
    }&lt;br /&gt;
    if ((y + diameter/2 &amp;gt;= height) || (y - diameter/2 &amp;lt;= 0)) {&lt;br /&gt;
      ydirection *= -1;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Måden metoden virker på er at den lægger hastigheden til boldens position (både x og y), og hvis boldens position (både i x og y) er kommet uden for rammen, så ændres retningen for enten x eller y.&lt;br /&gt;
&lt;br /&gt;
For at kunne vise bolden er der en display() metode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  void display() {&lt;br /&gt;
    ellipse(x, y, diameter, diameter);&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Den sidste metode hedder contains(), og den tager en position som parameter til metoden. Der undersøges så om den position ligger inden for bolden ved at se om afstanden mellem boldens center og den testede position er mindre end den halve diameter. Hvis den er inden for bolden, så returneres true, ellers returneres false:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  boolean contains(float x, float y) {&lt;br /&gt;
    float d = dist(x, y, this.x, this.y);&lt;br /&gt;
    if (d &amp;lt; diameter/2) {&lt;br /&gt;
      return true;&lt;br /&gt;
    } else {&lt;br /&gt;
      return false;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
====Oprettelse af ny bold====&lt;br /&gt;
I den oprindelige kode undersøges om der er klikket på en bold, ved at alle bolde løbes igennem i mousePressed() funktionen, og med metoden contains undersøges om der er klikket på en bold. Denne måde at undersøge alle bolde på beholdes.&lt;br /&gt;
&lt;br /&gt;
Som omtalt er det ikke den smarteste måde til at dele bolden op i to, der anvendes. Som det ses i koden herunder, så appendes der to nye bolde på med den oprindelige bolds x- og y-position på samt tilfældige x- og y-hastigheder. Disse to bolde lægges i slutningen af arrayet. Derefter anvendes shorten&amp;lt;ref&amp;gt;[https://processing.org/reference/shorten_.html Processings shorten metode til arrays]&amp;lt;/ref&amp;gt; til at fjerne et element, men da det element der fjernes er det sidste element i arrayet, så fjernes der bare den sidst oprettede bold.&lt;br /&gt;
&lt;br /&gt;
Hvis man var tilfreds med den opførsel, så kunne man blot fjerne kodelinjen med den anden append og kodelinjen med shorten. Så ville man have samme funktion.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
    if (balls[i].contains(mouseX, mouseY)) {&lt;br /&gt;
      balls = (Ball[]) append(balls, new Ball(balls[i].x, balls[i].y, random(-5, 5), random(-5, 5)));&lt;br /&gt;
      balls = (Ball[]) append(balls, new Ball(balls[i].x, balls[i].y, random(-5, 5), random(-5, 5)));&lt;br /&gt;
      balls = (Ball[]) shorten(balls);&lt;br /&gt;
      break;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Den nye bold der oprettes får bare en tilfældig retning, og den oprindelige bold fortsætter bare i den retning den var på vej i. Det er ikke den opførsel der ønskes i spillet. Der ønskes i stedet at det ser ud som om bolden &amp;quot;splittes op&amp;quot; i 2 bolde, og den opførsel laves ved at lade den oprindelige bold ændre 30 grader til den ene side, og den nye bold får 30 grader til den anden side.&lt;br /&gt;
&lt;br /&gt;
For at gøre dette, så oprettes der en metode multiply() i klassen Ball. Denne metode returnerer en ny bold af typen Ball, så nu kan koden i museklikket skrives som følger:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
    if (balls[i].contains(mouseX, mouseY)) {&lt;br /&gt;
      balls = (Ball[]) append(balls, balls[i].multiply());&lt;br /&gt;
      break;&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Som det kan ses, så appendes der en ny bold ind i balls-arrayet, ud fra metoden multiply().&lt;br /&gt;
&lt;br /&gt;
Metoden multiply() oprettes inde i klassen med følgende kode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  Ball multiply() {&lt;br /&gt;
    xspeed *= xdirection;&lt;br /&gt;
    yspeed *= ydirection;&lt;br /&gt;
    xdirection = 1;&lt;br /&gt;
    ydirection = 1;&lt;br /&gt;
    float speed = dist(0, 0, xspeed, yspeed);&lt;br /&gt;
    float angle = acos(xspeed / speed);&lt;br /&gt;
    if (yspeed &amp;lt; 0) angle = 0.0 - angle;&lt;br /&gt;
    speed *= 1.5;&lt;br /&gt;
    xspeed = speed * cos(angle + PI / 6);&lt;br /&gt;
    yspeed = speed * sin(angle + PI / 6);&lt;br /&gt;
    Ball b = new Ball(x, y, speed * cos(angle - PI / 6), speed * sin(angle - PI / 6));&lt;br /&gt;
    return b;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Først regnes retningen over i xspeed og yspeed, så de kan være både positive og negative. På den måde indeholder de to variabler retningen.&lt;br /&gt;
&lt;br /&gt;
Dernæst omregnes x- og y-hastigheden til en samlet hastighed speed og en vinkel angle, som kan være mellem +PI og -PI (+/- 180 grader).&lt;br /&gt;
&lt;br /&gt;
Begge bolde skal bevæge sig hurtigere efter de er delt, så spillet gradvist bliver sværere, derfor ganges hastigheden med 1,5.&lt;br /&gt;
&lt;br /&gt;
Den oprindelige bold får nu en ny retning, ved at udregne x- og y-hastigheden ud fra den nye hastighed og vinklen plus 30 grader.&lt;br /&gt;
&lt;br /&gt;
Til sidst oprettes en ny bold med samme position som den oprindelige og en x- og y-hastighed udregnet fra den oprindelige bolds hastighed og vinklen minus 30 grader. Denne bold returneres fra metoden.&lt;br /&gt;
==Referencer== &lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Programmering}}&lt;br /&gt;
&lt;br /&gt;
[[Kategori:Programmering teknik]]&lt;/div&gt;</summary>
		<author><name>Bar</name></author>
	</entry>
	<entry>
		<id>https://www.htxarduino.dk/index.php?title=Programmering_med_ChatGPT&amp;diff=5389</id>
		<title>Programmering med ChatGPT</title>
		<link rel="alternate" type="text/html" href="https://www.htxarduino.dk/index.php?title=Programmering_med_ChatGPT&amp;diff=5389"/>
		<updated>2024-03-16T16:20:26Z</updated>

		<summary type="html">&lt;p&gt;Bar: /* Metodeafsnit med omtale af ChatGPT */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Det er ikke så svært at få ChatGPT&amp;lt;ref&amp;gt;[https://chat.openai.com/auth/login ChatGPT Login] - Indgangen til ChatGPT&amp;lt;/ref&amp;gt; til at lave kode, der skal man blot beskrive hvad man gerne vil have programmet til at gøre, og så kopiere den kode, der kommer ud af det - det giver tit ret gode resultater.&lt;br /&gt;
&lt;br /&gt;
Problemet med at anvende ChatGPT i forbindelse med skoleprojekter er, at man har forståelsen med i det, og at man ikke kan blive anklaget for plagiat.&lt;br /&gt;
&lt;br /&gt;
==Hvad må man ikke i en skoleprojekt==&lt;br /&gt;
*Man må ikke kopiere kode, som man ikke selv har skrevet, til et programmeringsprodukt uden at man angiver en kilde. Det er uanset hvor koden stammer fra, også selvom man har brugt ChatGPT til at &amp;quot;udvikle&amp;quot; koden.&lt;br /&gt;
*Man må ikke aflevere et produkt hvor de primære dele af koden er kopieret, heller ikke selvom man kildehenviser.&lt;br /&gt;
*Man må ikke få ChatGPT til at dokumentere sin kode, ved at man kopierer ChatGPT&#039;s beskrivelse ind i sin dokumentation af koden.&lt;br /&gt;
&lt;br /&gt;
De beskrevne eksempler er at betragte som plagiat, og vil blive håndteret efter skolens ordensregler, hvilket i værste fald kan ende med at et fag annulleres eller man bliver bortvist fra uddannelsen.&lt;br /&gt;
==Hvad er tilladt med ChatGPT==&lt;br /&gt;
På samme måde som man må anvende kilder fra internettet, så må man i programmerings-faget i gymnasiet anvende ChatGPT i udviklingen af kode til et programmeringsprodukt. Dette er blevet tilladt via en revidering af vejledningen til faget&amp;lt;ref&amp;gt;[https://www.uvm.dk/-/media/filer/uvm/udd/gym/pdf23/aug/vejledninger/valgfag/230807-programmering-c--valgfag.pdf Vejledning] til Valgfaget Programmering C&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
I vejledningen står der som følger:&lt;br /&gt;
&lt;br /&gt;
: &#039;&#039;&amp;quot;brug af internettet er tilladt som fagligt hjælpemiddel ved de mundtlige prøver, inkluderer de tilladte hjælpemidler anvendelsen af chatbots og lignende på en måde, som afspejler, hvordan man arbejder i den daglige undervisning. Dette kunne fx være brug af ChatGPT til at debugge kode.&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Det skal altså afspejle den normale brug, som man også har ved at bruge internettet. Som angivet under hvad man ikke må, så er den normale brug, at man anvender information til at lære et programmere, men at man ikke tager så meget af sit produkt fra nettet, så man ikke har en forståelse af hvordan produktet er sammensat.&lt;br /&gt;
&lt;br /&gt;
Videre i vejledningen står der:&lt;br /&gt;
&lt;br /&gt;
: &#039;&#039;&amp;quot;I forhold til denne type hjælpemidler er det vigtigt at være opmærksom på, at den tilladte anvendelse er betinget af, at hjælpemidlerne kun benyttes i et omfang, hvor prøvebesvarelsen er selvstændig og udelukkende elevens egen.&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Igen understreges at det der afleveres skal være elevens selvstændigt udviklede produkt og dokumentation, hvor man på normal vis anvender internettet som et værktøj til at bibringe forståelse.&lt;br /&gt;
&lt;br /&gt;
==Problemet med ChatGPT==&lt;br /&gt;
Ligesom man ikke kan kilde-henvise til &amp;quot;google&amp;quot;, for at angive at man har fundet informationer på nettet, så kan man heller ikke kildehenvise til ChatGPT direkte som en kilde.&lt;br /&gt;
&lt;br /&gt;
Når man finder informationer med google&#039;, så skal man angive hvor på nettet man har fundet dem med så præcis en kildehenvisning, at man kan se den information der er blevet anvendt.&lt;br /&gt;
&lt;br /&gt;
Denne type henvisning kan man ikke lave i forhold til ChatGPT, da sprogmodellen der ligger bag ChatGPT konstant udvikler sig, samt at de svar sprogmodellen giver her et randomiseret element indbygget, som er med til at give bedre svar&amp;lt;ref&amp;gt;[https://www.it-vest.dk/arrangementer/sig-webinar-14-marts-2024-kunstig-intelligens-og-chatgpt-hvordan-virker-det-og-skal-vi-bare-opgive-undervisning-og-eksamen Webinar om kunstig intelligens]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Her er man altså nødt til at tage andre metoder i brug, for at kunne dokumentere at man har udviklet sit produkt ordentligt og redeligt.&lt;br /&gt;
==Kildehenvisninger i dokumentation==&lt;br /&gt;
Der kan være forskellige standarder for hvordan man kildehenviser i forskellige uddannelser, dette er skrevet med udgangspunkt i at man anvender Word bibliografi-værktøj og her vist med en Harvard-lignende standard&amp;lt;ref&amp;gt;[https://holstebro-htx.dk/index.php/Word_Kildeliste Kildelister] anvendt i Microsoft Word&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Normal Internet-kilde til kode===&lt;br /&gt;
I dette eksempel er der angivet hvordan man ville dokumentere at man har anvendt kode fra et bibliotek til noget hardware på en [[Arduino]]. I det tænkte eksempel er det en 4 kanals AD-konverter&amp;lt;ref&amp;gt;[https://arduinotech.dk/shop/ads1115-module-4-channel-16-bit-i2c-adc-with-pro-gain-amplifier 4 kanals AD-konverter] fra ArduinoTech&amp;lt;/ref&amp;gt;, der er købt som modul.&lt;br /&gt;
&lt;br /&gt;
For at kunne anvende modulet i koden skal der kommunikeres med modulet på en måde, som er angivet i beskrivelsen af modulet - det er dog ikke nødvendigt at sætte sig ind i den grundlæggende kommunikation, hvis man blot ønsker at få værdier ind i sin software. Som en dokumentation for hvordan man anvender biblioteket kan man skrive følgende:&lt;br /&gt;
&lt;br /&gt;
====Eksempel på dokumentation====&lt;br /&gt;
Til at hente værdierne fra den 4 kanals AD-konverter anvendes et bibliotek fundet på GitHub (Singh, 2018) som kan indlæse de analoge spændinger.&lt;br /&gt;
Til at sætte AD-konverteren rigtigt op, til at kunne læse 4 spændinger, så anvendes eksemplet ”ADS1115_SingleEnded.ino” og i setup skrives følgende kode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
    ads.getAddr_ADS1115(ADS1115_DEFAULT_ADDRESS);   // 0x48, 1001 000 (ADDR = GND)&lt;br /&gt;
    ads.setGain(GAIN_TWO);          // 2x gain   +/- 2.048V  1 bit = 0.0625mV (default)&lt;br /&gt;
    ads.setMode(MODE_CONTIN);       // Continuous conversion mode&lt;br /&gt;
    ads.setRate(RATE_128);          // 128SPS (default)&lt;br /&gt;
    ads.setOSMode(OSMODE_SINGLE);   // Set to start a single-conversion&lt;br /&gt;
    ads.begin();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
I [[loop()]] testes i første omgang, om det kan lade sig gøre at læse de 4 kanaler. Dette gøres ved at afvikle følgende testkode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
    address = ads.ads_i2cAddress;&lt;br /&gt;
    Wire.beginTransmission(address);&lt;br /&gt;
    error = Wire.endTransmission();&lt;br /&gt;
    if (error == 0)&lt;br /&gt;
    {&lt;br /&gt;
        int16_t adc0, adc1, adc2, adc3;&lt;br /&gt;
&lt;br /&gt;
        adc0 = ads.Measure_SingleEnded(0);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 1: &amp;quot;);&lt;br /&gt;
        Serial.println(adc0);&lt;br /&gt;
        adc1 = ads.Measure_SingleEnded(1);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 2: &amp;quot;);&lt;br /&gt;
        Serial.println(adc1);&lt;br /&gt;
        adc2 = ads.Measure_SingleEnded(2);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 3: &amp;quot;);&lt;br /&gt;
        Serial.println(adc2);&lt;br /&gt;
        adc3 = ads.Measure_SingleEnded(3);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 4: &amp;quot;);&lt;br /&gt;
        Serial.println(adc3);&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Denne test giver det ønskede resultat.&lt;br /&gt;
&lt;br /&gt;
Ud fra denne beskrivelse viser man, at man tager andres kode, og anvender ind i sit eget projekt, og man angiver præcist i sin beskrivelse hvad man har taget fra andres kode.&lt;br /&gt;
&lt;br /&gt;
I kildelisten vil kilden optræde på følgende måde:&lt;br /&gt;
&lt;br /&gt;
Singh, Y., 2018. Arduino Library ADS1115 16 bit 4 channel ADC. [Online] &amp;lt;br /&amp;gt;&lt;br /&gt;
Available at: https://github.com/ncdcommunity/Arduino_Library_ADS1115_16Bit_4Channel_ADC&amp;lt;br /&amp;gt;&lt;br /&gt;
[Senest hentet eller vist den 15 marts 2024].&lt;br /&gt;
&lt;br /&gt;
===ChatGPT som kilde til kode===&lt;br /&gt;
Hvis man forstår at prompte fornuftigt, så er ChatGPT faktisk ret god til at foreslå kode, der kan anvendes, men ligesom det er plagiat hvis man kopierer fra nettet, så er det plagiat, hvis man lader ChatGPT skrive store dele af ens program for sig.&lt;br /&gt;
&lt;br /&gt;
Som det er formuleret i vejledningen til både programmering C og B, så kan man anvende ChatGPT til hjælp i fejlfinding af kode. For at kunne kildehenvise korrekt til hjælp med fejlfinding, så skal man angive hvad man har promptet til ChatGPT og hvad den har svaret - det kan placeres i bilag.&lt;br /&gt;
&lt;br /&gt;
En anden ting, som også er OK at få hjælp med er, at komme i gang med programmet - det er denne problematik der her gives et eksempel på. I eksemplet beskrives hvad man skal skrive i sin dokumentation, når man har anvendt denne hjælp, og der er forslag til hvordan man kommer videre i projektet.&lt;br /&gt;
&lt;br /&gt;
Konkret er det starten på udviklingen af et lille spil med bolde i et vindue, udviklet i Processing- der tages udgangspunkt i.&lt;br /&gt;
&lt;br /&gt;
====Metodeafsnit med omtale af ChatGPT====&lt;br /&gt;
Når man anvender CharGPT, så skal man dokumentere hvordan man har gjort det, og hvilke overvejelser der ligger bag det. Det betegnes i rapportskrivning som et metodeafsnit. Det kunne i dette eksempel lyde:&lt;br /&gt;
&lt;br /&gt;
For at få en fornuftig start på programkoden er der brugt ChatGPT til at få rammerne på koden etableret, og til at få et system, så der kan optræde flere bolde i programvinduet. Det er ChatGPT 3.5 (OpenAI, 2023) der er anvendt til denne hjælp. Til programstarten blev der promptet efter at få et programvindue på 800x600 hvor en bold bevæger sig rundt. Den foreslåede kode blev kopieret ind i processings IDE (Processing, 2024) og testet – den opførte sig som forventet.&lt;br /&gt;
&lt;br /&gt;
Derefter blev der promptet efter at få den bold der bevægede sig til at dele sig op i to, når man klikker på den med musen. Dette resulterede i en væsentligt anderledes kode, som igen blev kopieret ind i processing og testet, og igen med et acceptabelt resultat. Dialogen med ChatGPT (OpenAI, 2023) og herunder de to koder, kan ses i bilag 1.&lt;br /&gt;
&lt;br /&gt;
Herefter er resten af koden udviklet på traditionel vis, hvor første trin var at dokumentere princippet i den foreslåede kode, specielt den Ball klasse der blev introduceret for at kunne arbejde med flere bolde i vinduet.&lt;br /&gt;
&lt;br /&gt;
Det nævnte bilag 1 [[media:ChatGPT-dialog-1.pdf|kan ses i denne PDF]].&lt;br /&gt;
&lt;br /&gt;
====Dokumentation af koden udviklet af ChatGPT====&lt;br /&gt;
Da der skulle kunne dannes nye bolde så oprettes der en klasse, som ChatGPT skriver det i dialogen i Bilag 1:&lt;br /&gt;
&lt;br /&gt;
: &#039;&#039;&amp;quot;Dette kodeeksempel opretter en klasse kaldet Ball, som repræsenterer boldobjekterne. Når musen klikkes, kontrolleres det, om musens position er inden for en bold. Hvis det er tilfældet, oprettes to nye boldobjekter, der bevæger sig i forskellige retninger, og den originale bold fjernes fra arrayet.&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Ved at teste koden kan man se at det ikke er det helt rigtige den formulerer - der oprettes godt nok to nye bold-objekter, men det er ikke den oprindelige bold der fjernes, det er den ene af de ny-oprettede bolde. Det kan ses ved at de to bolde kommer i samme position, og den ene fortsætter i samme retning (den oprindelige), mens den ny-oprettede går i en tilfældig retning. Dette rettes til senere i dokumentationen under &amp;quot;oprettelse af ny bold&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
For at have en god struktur i koden, så placeres klassen Ball i en fil for sig kaldet Ball. Denne fil starter med at definere koden som en klasse med linjen:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
class Ball {&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Dernæst defineres klassens egenskaber, der er boldens position og hastighed samt en fast diameter. Ud over det er der en x- og y-retning defineret. Den anvendes til at sige om bolden bevæger sig i en positiv eller negativ retning, så de skifter mellem +1 og -1, når kanterne rammes.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  float x, y;&lt;br /&gt;
  float xspeed, yspeed;&lt;br /&gt;
  int diameter = 30;&lt;br /&gt;
  int xdirection = 1;&lt;br /&gt;
  int ydirection = 1;&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Der defineres to forskellige constructors til bolden. Den første anvendes til at danne den første bold med, hvor position og hastighed sættes tilfældigt.&lt;br /&gt;
&lt;br /&gt;
Her forudses et problem at der kan komme et randfænomen, hvis bolden dannes, så den ligger med noget uden for skærmen. Da det er tilfældigt; så er det sjældent problemet opstår. For at fremprovokere det oftere er det testet med en diameter på 200, hvor det kunne ses at bolden bliver &amp;quot;hængende&amp;quot; i kanten.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  Ball() {&lt;br /&gt;
    x = random(width);&lt;br /&gt;
    y = random(height);&lt;br /&gt;
    xspeed = random(0.5, 2);&lt;br /&gt;
    yspeed = random(0.5, 2);&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Dette rettes ved at omskrive de constructor til følgende kode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  Ball() {&lt;br /&gt;
    x = random(diameter / 2, width - diameter / 2);&lt;br /&gt;
    y = random(diameter / 2, height - diameter / 2);&lt;br /&gt;
    xspeed = random(0.5, 2);&lt;br /&gt;
    yspeed = random(0.5, 2);&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Den anden constructor tager fire parametre, der er positionen og hastigheden. Denne constructor anvendes, når der skal dannes nye bolde, hvor koden netop skal starte den nye bold i den oprindelige bolds position, og med en ny retning.&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  Ball(float x, float y, float xspeed, float yspeed) {&lt;br /&gt;
    this.x = x;&lt;br /&gt;
    this.y = y;&lt;br /&gt;
    this.xspeed = xspeed;&lt;br /&gt;
    this.yspeed = yspeed;&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Ud over disse standard ting til oprettelsen af objekter, så er der 3 metoder i klassen. Den første er en move() metode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  void move() {&lt;br /&gt;
    x = x + (xspeed * xdirection);&lt;br /&gt;
    y = y + (yspeed * ydirection);&lt;br /&gt;
&lt;br /&gt;
    if ((x + diameter/2 &amp;gt;= width) || (x - diameter/2 &amp;lt;= 0)) {&lt;br /&gt;
      xdirection *= -1;&lt;br /&gt;
    }&lt;br /&gt;
    if ((y + diameter/2 &amp;gt;= height) || (y - diameter/2 &amp;lt;= 0)) {&lt;br /&gt;
      ydirection *= -1;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Måden metoden virker på er at den lægger hastigheden til boldens position (både x og y), og hvis boldens position (både i x og y) er kommet uden for rammen, så ændres retningen for enten x eller y.&lt;br /&gt;
&lt;br /&gt;
For at kunne vise bolden er der en display() metode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  void display() {&lt;br /&gt;
    ellipse(x, y, diameter, diameter);&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Den sidste metode hedder contains(), og den tager en position som parameter til metoden. Der undersøges så om den position ligger inden for bolden ved at se om afstanden mellem boldens center og den testede position er mindre end den halve diameter. Hvis den er inden for bolden, så returneres true, ellers returneres false:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;C&amp;quot;&amp;gt;&lt;br /&gt;
  boolean contains(float x, float y) {&lt;br /&gt;
    float d = dist(x, y, this.x, this.y);&lt;br /&gt;
    if (d &amp;lt; diameter/2) {&lt;br /&gt;
      return true;&lt;br /&gt;
    } else {&lt;br /&gt;
      return false;&lt;br /&gt;
    }&lt;br /&gt;
  }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==Referencer== &lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Programmering}}&lt;br /&gt;
&lt;br /&gt;
[[Kategori:Programmering teknik]]&lt;/div&gt;</summary>
		<author><name>Bar</name></author>
	</entry>
	<entry>
		<id>https://www.htxarduino.dk/index.php?title=Programmering_med_ChatGPT&amp;diff=5388</id>
		<title>Programmering med ChatGPT</title>
		<link rel="alternate" type="text/html" href="https://www.htxarduino.dk/index.php?title=Programmering_med_ChatGPT&amp;diff=5388"/>
		<updated>2024-03-16T14:33:54Z</updated>

		<summary type="html">&lt;p&gt;Bar: /* Metodeafsnit med omtale af ChatGPT */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Det er ikke så svært at få ChatGPT&amp;lt;ref&amp;gt;[https://chat.openai.com/auth/login ChatGPT Login] - Indgangen til ChatGPT&amp;lt;/ref&amp;gt; til at lave kode, der skal man blot beskrive hvad man gerne vil have programmet til at gøre, og så kopiere den kode, der kommer ud af det - det giver tit ret gode resultater.&lt;br /&gt;
&lt;br /&gt;
Problemet med at anvende ChatGPT i forbindelse med skoleprojekter er, at man har forståelsen med i det, og at man ikke kan blive anklaget for plagiat.&lt;br /&gt;
&lt;br /&gt;
==Hvad må man ikke i en skoleprojekt==&lt;br /&gt;
*Man må ikke kopiere kode, som man ikke selv har skrevet, til et programmeringsprodukt uden at man angiver en kilde. Det er uanset hvor koden stammer fra, også selvom man har brugt ChatGPT til at &amp;quot;udvikle&amp;quot; koden.&lt;br /&gt;
*Man må ikke aflevere et produkt hvor de primære dele af koden er kopieret, heller ikke selvom man kildehenviser.&lt;br /&gt;
*Man må ikke få ChatGPT til at dokumentere sin kode, ved at man kopierer ChatGPT&#039;s beskrivelse ind i sin dokumentation af koden.&lt;br /&gt;
&lt;br /&gt;
De beskrevne eksempler er at betragte som plagiat, og vil blive håndteret efter skolens ordensregler, hvilket i værste fald kan ende med at et fag annulleres eller man bliver bortvist fra uddannelsen.&lt;br /&gt;
==Hvad er tilladt med ChatGPT==&lt;br /&gt;
På samme måde som man må anvende kilder fra internettet, så må man i programmerings-faget i gymnasiet anvende ChatGPT i udviklingen af kode til et programmeringsprodukt. Dette er blevet tilladt via en revidering af vejledningen til faget&amp;lt;ref&amp;gt;[https://www.uvm.dk/-/media/filer/uvm/udd/gym/pdf23/aug/vejledninger/valgfag/230807-programmering-c--valgfag.pdf Vejledning] til Valgfaget Programmering C&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
I vejledningen står der som følger:&lt;br /&gt;
&lt;br /&gt;
: &#039;&#039;&amp;quot;brug af internettet er tilladt som fagligt hjælpemiddel ved de mundtlige prøver, inkluderer de tilladte hjælpemidler anvendelsen af chatbots og lignende på en måde, som afspejler, hvordan man arbejder i den daglige undervisning. Dette kunne fx være brug af ChatGPT til at debugge kode.&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Det skal altså afspejle den normale brug, som man også har ved at bruge internettet. Som angivet under hvad man ikke må, så er den normale brug, at man anvender information til at lære et programmere, men at man ikke tager så meget af sit produkt fra nettet, så man ikke har en forståelse af hvordan produktet er sammensat.&lt;br /&gt;
&lt;br /&gt;
Videre i vejledningen står der:&lt;br /&gt;
&lt;br /&gt;
: &#039;&#039;&amp;quot;I forhold til denne type hjælpemidler er det vigtigt at være opmærksom på, at den tilladte anvendelse er betinget af, at hjælpemidlerne kun benyttes i et omfang, hvor prøvebesvarelsen er selvstændig og udelukkende elevens egen.&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Igen understreges at det der afleveres skal være elevens selvstændigt udviklede produkt og dokumentation, hvor man på normal vis anvender internettet som et værktøj til at bibringe forståelse.&lt;br /&gt;
&lt;br /&gt;
==Problemet med ChatGPT==&lt;br /&gt;
Ligesom man ikke kan kilde-henvise til &amp;quot;google&amp;quot;, for at angive at man har fundet informationer på nettet, så kan man heller ikke kildehenvise til ChatGPT direkte som en kilde.&lt;br /&gt;
&lt;br /&gt;
Når man finder informationer med google&#039;, så skal man angive hvor på nettet man har fundet dem med så præcis en kildehenvisning, at man kan se den information der er blevet anvendt.&lt;br /&gt;
&lt;br /&gt;
Denne type henvisning kan man ikke lave i forhold til ChatGPT, da sprogmodellen der ligger bag ChatGPT konstant udvikler sig, samt at de svar sprogmodellen giver her et randomiseret element indbygget, som er med til at give bedre svar&amp;lt;ref&amp;gt;[https://www.it-vest.dk/arrangementer/sig-webinar-14-marts-2024-kunstig-intelligens-og-chatgpt-hvordan-virker-det-og-skal-vi-bare-opgive-undervisning-og-eksamen Webinar om kunstig intelligens]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Her er man altså nødt til at tage andre metoder i brug, for at kunne dokumentere at man har udviklet sit produkt ordentligt og redeligt.&lt;br /&gt;
==Kildehenvisninger i dokumentation==&lt;br /&gt;
Der kan være forskellige standarder for hvordan man kildehenviser i forskellige uddannelser, dette er skrevet med udgangspunkt i at man anvender Word bibliografi-værktøj og her vist med en Harvard-lignende standard&amp;lt;ref&amp;gt;[https://holstebro-htx.dk/index.php/Word_Kildeliste Kildelister] anvendt i Microsoft Word&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Normal Internet-kilde til kode===&lt;br /&gt;
I dette eksempel er der angivet hvordan man ville dokumentere at man har anvendt kode fra et bibliotek til noget hardware på en [[Arduino]]. I det tænkte eksempel er det en 4 kanals AD-konverter&amp;lt;ref&amp;gt;[https://arduinotech.dk/shop/ads1115-module-4-channel-16-bit-i2c-adc-with-pro-gain-amplifier 4 kanals AD-konverter] fra ArduinoTech&amp;lt;/ref&amp;gt;, der er købt som modul.&lt;br /&gt;
&lt;br /&gt;
For at kunne anvende modulet i koden skal der kommunikeres med modulet på en måde, som er angivet i beskrivelsen af modulet - det er dog ikke nødvendigt at sætte sig ind i den grundlæggende kommunikation, hvis man blot ønsker at få værdier ind i sin software. Som en dokumentation for hvordan man anvender biblioteket kan man skrive følgende:&lt;br /&gt;
&lt;br /&gt;
====Eksempel på dokumentation====&lt;br /&gt;
Til at hente værdierne fra den 4 kanals AD-konverter anvendes et bibliotek fundet på GitHub (Singh, 2018) som kan indlæse de analoge spændinger.&lt;br /&gt;
Til at sætte AD-konverteren rigtigt op, til at kunne læse 4 spændinger, så anvendes eksemplet ”ADS1115_SingleEnded.ino” og i setup skrives følgende kode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
    ads.getAddr_ADS1115(ADS1115_DEFAULT_ADDRESS);   // 0x48, 1001 000 (ADDR = GND)&lt;br /&gt;
    ads.setGain(GAIN_TWO);          // 2x gain   +/- 2.048V  1 bit = 0.0625mV (default)&lt;br /&gt;
    ads.setMode(MODE_CONTIN);       // Continuous conversion mode&lt;br /&gt;
    ads.setRate(RATE_128);          // 128SPS (default)&lt;br /&gt;
    ads.setOSMode(OSMODE_SINGLE);   // Set to start a single-conversion&lt;br /&gt;
    ads.begin();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
I [[loop()]] testes i første omgang, om det kan lade sig gøre at læse de 4 kanaler. Dette gøres ved at afvikle følgende testkode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
    address = ads.ads_i2cAddress;&lt;br /&gt;
    Wire.beginTransmission(address);&lt;br /&gt;
    error = Wire.endTransmission();&lt;br /&gt;
    if (error == 0)&lt;br /&gt;
    {&lt;br /&gt;
        int16_t adc0, adc1, adc2, adc3;&lt;br /&gt;
&lt;br /&gt;
        adc0 = ads.Measure_SingleEnded(0);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 1: &amp;quot;);&lt;br /&gt;
        Serial.println(adc0);&lt;br /&gt;
        adc1 = ads.Measure_SingleEnded(1);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 2: &amp;quot;);&lt;br /&gt;
        Serial.println(adc1);&lt;br /&gt;
        adc2 = ads.Measure_SingleEnded(2);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 3: &amp;quot;);&lt;br /&gt;
        Serial.println(adc2);&lt;br /&gt;
        adc3 = ads.Measure_SingleEnded(3);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 4: &amp;quot;);&lt;br /&gt;
        Serial.println(adc3);&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Denne test giver det ønskede resultat.&lt;br /&gt;
&lt;br /&gt;
Ud fra denne beskrivelse viser man, at man tager andres kode, og anvender ind i sit eget projekt, og man angiver præcist i sin beskrivelse hvad man har taget fra andres kode.&lt;br /&gt;
&lt;br /&gt;
I kildelisten vil kilden optræde på følgende måde:&lt;br /&gt;
&lt;br /&gt;
Singh, Y., 2018. Arduino Library ADS1115 16 bit 4 channel ADC. [Online] &amp;lt;br /&amp;gt;&lt;br /&gt;
Available at: https://github.com/ncdcommunity/Arduino_Library_ADS1115_16Bit_4Channel_ADC&amp;lt;br /&amp;gt;&lt;br /&gt;
[Senest hentet eller vist den 15 marts 2024].&lt;br /&gt;
&lt;br /&gt;
===ChatGPT som kilde til kode===&lt;br /&gt;
Hvis man forstår at prompte fornuftigt, så er ChatGPT faktisk ret god til at foreslå kode, der kan anvendes, men ligesom det er plagiat hvis man kopierer fra nettet, så er det plagiat, hvis man lader ChatGPT skrive store dele af ens program for sig.&lt;br /&gt;
&lt;br /&gt;
Som det er formuleret i vejledningen til både programmering C og B, så kan man anvende ChatGPT til hjælp i fejlfinding af kode. For at kunne kildehenvise korrekt til hjælp med fejlfinding, så skal man angive hvad man har promptet til ChatGPT og hvad den har svaret - det kan placeres i bilag.&lt;br /&gt;
&lt;br /&gt;
En anden ting, som også er OK at få hjælp med er, at komme i gang med programmet - det er denne problematik der her gives et eksempel på. I eksemplet beskrives hvad man skal skrive i sin dokumentation, når man har anvendt denne hjælp, og der er forslag til hvordan man kommer videre i projektet.&lt;br /&gt;
&lt;br /&gt;
Konkret er det starten på udviklingen af et lille spil med bolde i et vindue, udviklet i Processing- der tages udgangspunkt i.&lt;br /&gt;
&lt;br /&gt;
====Metodeafsnit med omtale af ChatGPT====&lt;br /&gt;
Når man anvender CharGPT, så skal man dokumentere hvordan man har gjort det, og hvilke overvejelser der ligger bag det. Det betegnes i rapportskrivning som et metodeafsnit. Det kunne i dette eksempel lyde:&lt;br /&gt;
&lt;br /&gt;
For at få en fornuftig start på programkoden er der brugt ChatGPT til at få rammerne på koden etableret, og til at få et system, så der kan optræde flere bolde i programvinduet. Det er ChatGPT 3.5 (OpenAI, 2023) der er anvendt til denne hjælp. Til programstarten blev der promptet efter at få et programvindue på 800x600 hvor en bold bevæger sig rundt. Den foreslåede kode blev kopieret ind i processings IDE (Processing, 2024) og testet – den opførte sig som forventet.&lt;br /&gt;
&lt;br /&gt;
Derefter blev der promptet efter at få den bold der bevægede sig til at dele sig op i to, når man klikker på den med musen. Dette resulterede i en væsentligt anderledes kode, som igen blev kopieret ind i processing og testet, og igen med et acceptabelt resultat. Dialogen med ChatGPT (OpenAI, 2023) og herunder de to koder, kan ses i bilag 1.&lt;br /&gt;
&lt;br /&gt;
Herefter er resten af koden udviklet på traditionel vis, hvor første trin var at dokumentere princippet i den foreslåede kode, specielt den Ball klasse der blev introduceret for at kunne arbejde med flere bolde i vinduet.&lt;br /&gt;
&lt;br /&gt;
Det nævnte bilag 1 [[media:ChatGPT-dialog-1.pdf|kan ses i denne PDF]].&lt;br /&gt;
&lt;br /&gt;
==Referencer== &lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Programmering}}&lt;br /&gt;
&lt;br /&gt;
[[Kategori:Programmering teknik]]&lt;/div&gt;</summary>
		<author><name>Bar</name></author>
	</entry>
	<entry>
		<id>https://www.htxarduino.dk/index.php?title=Fil:ChatGPT-dialog-1.pdf&amp;diff=5387</id>
		<title>Fil:ChatGPT-dialog-1.pdf</title>
		<link rel="alternate" type="text/html" href="https://www.htxarduino.dk/index.php?title=Fil:ChatGPT-dialog-1.pdf&amp;diff=5387"/>
		<updated>2024-03-16T14:33:14Z</updated>

		<summary type="html">&lt;p&gt;Bar: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Bar</name></author>
	</entry>
	<entry>
		<id>https://www.htxarduino.dk/index.php?title=Programmering_med_ChatGPT&amp;diff=5386</id>
		<title>Programmering med ChatGPT</title>
		<link rel="alternate" type="text/html" href="https://www.htxarduino.dk/index.php?title=Programmering_med_ChatGPT&amp;diff=5386"/>
		<updated>2024-03-16T14:32:01Z</updated>

		<summary type="html">&lt;p&gt;Bar: /* Referencer */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Det er ikke så svært at få ChatGPT&amp;lt;ref&amp;gt;[https://chat.openai.com/auth/login ChatGPT Login] - Indgangen til ChatGPT&amp;lt;/ref&amp;gt; til at lave kode, der skal man blot beskrive hvad man gerne vil have programmet til at gøre, og så kopiere den kode, der kommer ud af det - det giver tit ret gode resultater.&lt;br /&gt;
&lt;br /&gt;
Problemet med at anvende ChatGPT i forbindelse med skoleprojekter er, at man har forståelsen med i det, og at man ikke kan blive anklaget for plagiat.&lt;br /&gt;
&lt;br /&gt;
==Hvad må man ikke i en skoleprojekt==&lt;br /&gt;
*Man må ikke kopiere kode, som man ikke selv har skrevet, til et programmeringsprodukt uden at man angiver en kilde. Det er uanset hvor koden stammer fra, også selvom man har brugt ChatGPT til at &amp;quot;udvikle&amp;quot; koden.&lt;br /&gt;
*Man må ikke aflevere et produkt hvor de primære dele af koden er kopieret, heller ikke selvom man kildehenviser.&lt;br /&gt;
*Man må ikke få ChatGPT til at dokumentere sin kode, ved at man kopierer ChatGPT&#039;s beskrivelse ind i sin dokumentation af koden.&lt;br /&gt;
&lt;br /&gt;
De beskrevne eksempler er at betragte som plagiat, og vil blive håndteret efter skolens ordensregler, hvilket i værste fald kan ende med at et fag annulleres eller man bliver bortvist fra uddannelsen.&lt;br /&gt;
==Hvad er tilladt med ChatGPT==&lt;br /&gt;
På samme måde som man må anvende kilder fra internettet, så må man i programmerings-faget i gymnasiet anvende ChatGPT i udviklingen af kode til et programmeringsprodukt. Dette er blevet tilladt via en revidering af vejledningen til faget&amp;lt;ref&amp;gt;[https://www.uvm.dk/-/media/filer/uvm/udd/gym/pdf23/aug/vejledninger/valgfag/230807-programmering-c--valgfag.pdf Vejledning] til Valgfaget Programmering C&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
I vejledningen står der som følger:&lt;br /&gt;
&lt;br /&gt;
: &#039;&#039;&amp;quot;brug af internettet er tilladt som fagligt hjælpemiddel ved de mundtlige prøver, inkluderer de tilladte hjælpemidler anvendelsen af chatbots og lignende på en måde, som afspejler, hvordan man arbejder i den daglige undervisning. Dette kunne fx være brug af ChatGPT til at debugge kode.&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Det skal altså afspejle den normale brug, som man også har ved at bruge internettet. Som angivet under hvad man ikke må, så er den normale brug, at man anvender information til at lære et programmere, men at man ikke tager så meget af sit produkt fra nettet, så man ikke har en forståelse af hvordan produktet er sammensat.&lt;br /&gt;
&lt;br /&gt;
Videre i vejledningen står der:&lt;br /&gt;
&lt;br /&gt;
: &#039;&#039;&amp;quot;I forhold til denne type hjælpemidler er det vigtigt at være opmærksom på, at den tilladte anvendelse er betinget af, at hjælpemidlerne kun benyttes i et omfang, hvor prøvebesvarelsen er selvstændig og udelukkende elevens egen.&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Igen understreges at det der afleveres skal være elevens selvstændigt udviklede produkt og dokumentation, hvor man på normal vis anvender internettet som et værktøj til at bibringe forståelse.&lt;br /&gt;
&lt;br /&gt;
==Problemet med ChatGPT==&lt;br /&gt;
Ligesom man ikke kan kilde-henvise til &amp;quot;google&amp;quot;, for at angive at man har fundet informationer på nettet, så kan man heller ikke kildehenvise til ChatGPT direkte som en kilde.&lt;br /&gt;
&lt;br /&gt;
Når man finder informationer med google&#039;, så skal man angive hvor på nettet man har fundet dem med så præcis en kildehenvisning, at man kan se den information der er blevet anvendt.&lt;br /&gt;
&lt;br /&gt;
Denne type henvisning kan man ikke lave i forhold til ChatGPT, da sprogmodellen der ligger bag ChatGPT konstant udvikler sig, samt at de svar sprogmodellen giver her et randomiseret element indbygget, som er med til at give bedre svar&amp;lt;ref&amp;gt;[https://www.it-vest.dk/arrangementer/sig-webinar-14-marts-2024-kunstig-intelligens-og-chatgpt-hvordan-virker-det-og-skal-vi-bare-opgive-undervisning-og-eksamen Webinar om kunstig intelligens]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Her er man altså nødt til at tage andre metoder i brug, for at kunne dokumentere at man har udviklet sit produkt ordentligt og redeligt.&lt;br /&gt;
==Kildehenvisninger i dokumentation==&lt;br /&gt;
Der kan være forskellige standarder for hvordan man kildehenviser i forskellige uddannelser, dette er skrevet med udgangspunkt i at man anvender Word bibliografi-værktøj og her vist med en Harvard-lignende standard&amp;lt;ref&amp;gt;[https://holstebro-htx.dk/index.php/Word_Kildeliste Kildelister] anvendt i Microsoft Word&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Normal Internet-kilde til kode===&lt;br /&gt;
I dette eksempel er der angivet hvordan man ville dokumentere at man har anvendt kode fra et bibliotek til noget hardware på en [[Arduino]]. I det tænkte eksempel er det en 4 kanals AD-konverter&amp;lt;ref&amp;gt;[https://arduinotech.dk/shop/ads1115-module-4-channel-16-bit-i2c-adc-with-pro-gain-amplifier 4 kanals AD-konverter] fra ArduinoTech&amp;lt;/ref&amp;gt;, der er købt som modul.&lt;br /&gt;
&lt;br /&gt;
For at kunne anvende modulet i koden skal der kommunikeres med modulet på en måde, som er angivet i beskrivelsen af modulet - det er dog ikke nødvendigt at sætte sig ind i den grundlæggende kommunikation, hvis man blot ønsker at få værdier ind i sin software. Som en dokumentation for hvordan man anvender biblioteket kan man skrive følgende:&lt;br /&gt;
&lt;br /&gt;
====Eksempel på dokumentation====&lt;br /&gt;
Til at hente værdierne fra den 4 kanals AD-konverter anvendes et bibliotek fundet på GitHub (Singh, 2018) som kan indlæse de analoge spændinger.&lt;br /&gt;
Til at sætte AD-konverteren rigtigt op, til at kunne læse 4 spændinger, så anvendes eksemplet ”ADS1115_SingleEnded.ino” og i setup skrives følgende kode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
    ads.getAddr_ADS1115(ADS1115_DEFAULT_ADDRESS);   // 0x48, 1001 000 (ADDR = GND)&lt;br /&gt;
    ads.setGain(GAIN_TWO);          // 2x gain   +/- 2.048V  1 bit = 0.0625mV (default)&lt;br /&gt;
    ads.setMode(MODE_CONTIN);       // Continuous conversion mode&lt;br /&gt;
    ads.setRate(RATE_128);          // 128SPS (default)&lt;br /&gt;
    ads.setOSMode(OSMODE_SINGLE);   // Set to start a single-conversion&lt;br /&gt;
    ads.begin();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
I [[loop()]] testes i første omgang, om det kan lade sig gøre at læse de 4 kanaler. Dette gøres ved at afvikle følgende testkode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
    address = ads.ads_i2cAddress;&lt;br /&gt;
    Wire.beginTransmission(address);&lt;br /&gt;
    error = Wire.endTransmission();&lt;br /&gt;
    if (error == 0)&lt;br /&gt;
    {&lt;br /&gt;
        int16_t adc0, adc1, adc2, adc3;&lt;br /&gt;
&lt;br /&gt;
        adc0 = ads.Measure_SingleEnded(0);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 1: &amp;quot;);&lt;br /&gt;
        Serial.println(adc0);&lt;br /&gt;
        adc1 = ads.Measure_SingleEnded(1);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 2: &amp;quot;);&lt;br /&gt;
        Serial.println(adc1);&lt;br /&gt;
        adc2 = ads.Measure_SingleEnded(2);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 3: &amp;quot;);&lt;br /&gt;
        Serial.println(adc2);&lt;br /&gt;
        adc3 = ads.Measure_SingleEnded(3);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 4: &amp;quot;);&lt;br /&gt;
        Serial.println(adc3);&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Denne test giver det ønskede resultat.&lt;br /&gt;
&lt;br /&gt;
Ud fra denne beskrivelse viser man, at man tager andres kode, og anvender ind i sit eget projekt, og man angiver præcist i sin beskrivelse hvad man har taget fra andres kode.&lt;br /&gt;
&lt;br /&gt;
I kildelisten vil kilden optræde på følgende måde:&lt;br /&gt;
&lt;br /&gt;
Singh, Y., 2018. Arduino Library ADS1115 16 bit 4 channel ADC. [Online] &amp;lt;br /&amp;gt;&lt;br /&gt;
Available at: https://github.com/ncdcommunity/Arduino_Library_ADS1115_16Bit_4Channel_ADC&amp;lt;br /&amp;gt;&lt;br /&gt;
[Senest hentet eller vist den 15 marts 2024].&lt;br /&gt;
&lt;br /&gt;
===ChatGPT som kilde til kode===&lt;br /&gt;
Hvis man forstår at prompte fornuftigt, så er ChatGPT faktisk ret god til at foreslå kode, der kan anvendes, men ligesom det er plagiat hvis man kopierer fra nettet, så er det plagiat, hvis man lader ChatGPT skrive store dele af ens program for sig.&lt;br /&gt;
&lt;br /&gt;
Som det er formuleret i vejledningen til både programmering C og B, så kan man anvende ChatGPT til hjælp i fejlfinding af kode. For at kunne kildehenvise korrekt til hjælp med fejlfinding, så skal man angive hvad man har promptet til ChatGPT og hvad den har svaret - det kan placeres i bilag.&lt;br /&gt;
&lt;br /&gt;
En anden ting, som også er OK at få hjælp med er, at komme i gang med programmet - det er denne problematik der her gives et eksempel på. I eksemplet beskrives hvad man skal skrive i sin dokumentation, når man har anvendt denne hjælp, og der er forslag til hvordan man kommer videre i projektet.&lt;br /&gt;
&lt;br /&gt;
Konkret er det starten på udviklingen af et lille spil med bolde i et vindue, udviklet i Processing- der tages udgangspunkt i.&lt;br /&gt;
&lt;br /&gt;
====Metodeafsnit med omtale af ChatGPT====&lt;br /&gt;
Når man anvender CharGPT, så skal man dokumentere hvordan man har gjort det, og hvilke overvejelser der ligger bag det. Det betegnes i rapportskrivning som et metodeafsnit. Det kunne i dette eksempel lyde:&lt;br /&gt;
&lt;br /&gt;
For at få en fornuftig start på programkoden er der brugt ChatGPT til at få rammerne på koden etableret, og til at få et system, så der kan optræde flere bolde i programvinduet. Det er ChatGPT 3.5 (OpenAI, 2023) der er anvendt til denne hjælp. Til programstarten blev der promptet efter at få et programvindue på 800x600 hvor en bold bevæger sig rundt. Den foreslåede kode blev kopieret ind i processings IDE (Processing, 2024) og testet – den opførte sig som forventet.&lt;br /&gt;
&lt;br /&gt;
Derefter blev der promptet efter at få den bold der bevægede sig til at dele sig op i to, når man klikker på den med musen. Dette resulterede i en væsentligt anderledes kode, som igen blev kopieret ind i processing og testet, og igen med et acceptabelt resultat. Dialogen med ChatGPT (OpenAI, 2023) og herunder de to koder, kan ses i bilag 1.&lt;br /&gt;
&lt;br /&gt;
Herefter er resten af koden udviklet på traditionel vis, hvor første trin var at dokumentere princippet i den foreslåede kode, specielt den Ball klasse der blev introduceret for at kunne arbejde med flere bolde i vinduet.&lt;br /&gt;
&lt;br /&gt;
Det nævnte bilag 1 [[media:ChatGPT-dialog-1.pdf|kan ses i denne PDF]].&lt;br /&gt;
==Referencer== &lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Programmering}}&lt;br /&gt;
&lt;br /&gt;
[[Kategori:Programmering teknik]]&lt;/div&gt;</summary>
		<author><name>Bar</name></author>
	</entry>
	<entry>
		<id>https://www.htxarduino.dk/index.php?title=Programmering_med_ChatGPT&amp;diff=5385</id>
		<title>Programmering med ChatGPT</title>
		<link rel="alternate" type="text/html" href="https://www.htxarduino.dk/index.php?title=Programmering_med_ChatGPT&amp;diff=5385"/>
		<updated>2024-03-15T12:08:03Z</updated>

		<summary type="html">&lt;p&gt;Bar: /* Normal Internet-kilde til kode */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Det er ikke så svært at få ChatGPT&amp;lt;ref&amp;gt;[https://chat.openai.com/auth/login ChatGPT Login] - Indgangen til ChatGPT&amp;lt;/ref&amp;gt; til at lave kode, der skal man blot beskrive hvad man gerne vil have programmet til at gøre, og så kopiere den kode, der kommer ud af det - det giver tit ret gode resultater.&lt;br /&gt;
&lt;br /&gt;
Problemet med at anvende ChatGPT i forbindelse med skoleprojekter er, at man har forståelsen med i det, og at man ikke kan blive anklaget for plagiat.&lt;br /&gt;
&lt;br /&gt;
==Hvad må man ikke i en skoleprojekt==&lt;br /&gt;
*Man må ikke kopiere kode, som man ikke selv har skrevet, til et programmeringsprodukt uden at man angiver en kilde. Det er uanset hvor koden stammer fra, også selvom man har brugt ChatGPT til at &amp;quot;udvikle&amp;quot; koden.&lt;br /&gt;
*Man må ikke aflevere et produkt hvor de primære dele af koden er kopieret, heller ikke selvom man kildehenviser.&lt;br /&gt;
*Man må ikke få ChatGPT til at dokumentere sin kode, ved at man kopierer ChatGPT&#039;s beskrivelse ind i sin dokumentation af koden.&lt;br /&gt;
&lt;br /&gt;
De beskrevne eksempler er at betragte som plagiat, og vil blive håndteret efter skolens ordensregler, hvilket i værste fald kan ende med at et fag annulleres eller man bliver bortvist fra uddannelsen.&lt;br /&gt;
==Hvad er tilladt med ChatGPT==&lt;br /&gt;
På samme måde som man må anvende kilder fra internettet, så må man i programmerings-faget i gymnasiet anvende ChatGPT i udviklingen af kode til et programmeringsprodukt. Dette er blevet tilladt via en revidering af vejledningen til faget&amp;lt;ref&amp;gt;[https://www.uvm.dk/-/media/filer/uvm/udd/gym/pdf23/aug/vejledninger/valgfag/230807-programmering-c--valgfag.pdf Vejledning] til Valgfaget Programmering C&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
I vejledningen står der som følger:&lt;br /&gt;
&lt;br /&gt;
: &#039;&#039;&amp;quot;brug af internettet er tilladt som fagligt hjælpemiddel ved de mundtlige prøver, inkluderer de tilladte hjælpemidler anvendelsen af chatbots og lignende på en måde, som afspejler, hvordan man arbejder i den daglige undervisning. Dette kunne fx være brug af ChatGPT til at debugge kode.&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Det skal altså afspejle den normale brug, som man også har ved at bruge internettet. Som angivet under hvad man ikke må, så er den normale brug, at man anvender information til at lære et programmere, men at man ikke tager så meget af sit produkt fra nettet, så man ikke har en forståelse af hvordan produktet er sammensat.&lt;br /&gt;
&lt;br /&gt;
Videre i vejledningen står der:&lt;br /&gt;
&lt;br /&gt;
: &#039;&#039;&amp;quot;I forhold til denne type hjælpemidler er det vigtigt at være opmærksom på, at den tilladte anvendelse er betinget af, at hjælpemidlerne kun benyttes i et omfang, hvor prøvebesvarelsen er selvstændig og udelukkende elevens egen.&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Igen understreges at det der afleveres skal være elevens selvstændigt udviklede produkt og dokumentation, hvor man på normal vis anvender internettet som et værktøj til at bibringe forståelse.&lt;br /&gt;
&lt;br /&gt;
==Problemet med ChatGPT==&lt;br /&gt;
Ligesom man ikke kan kilde-henvise til &amp;quot;google&amp;quot;, for at angive at man har fundet informationer på nettet, så kan man heller ikke kildehenvise til ChatGPT direkte som en kilde.&lt;br /&gt;
&lt;br /&gt;
Når man finder informationer med google&#039;, så skal man angive hvor på nettet man har fundet dem med så præcis en kildehenvisning, at man kan se den information der er blevet anvendt.&lt;br /&gt;
&lt;br /&gt;
Denne type henvisning kan man ikke lave i forhold til ChatGPT, da sprogmodellen der ligger bag ChatGPT konstant udvikler sig, samt at de svar sprogmodellen giver her et randomiseret element indbygget, som er med til at give bedre svar&amp;lt;ref&amp;gt;[https://www.it-vest.dk/arrangementer/sig-webinar-14-marts-2024-kunstig-intelligens-og-chatgpt-hvordan-virker-det-og-skal-vi-bare-opgive-undervisning-og-eksamen Webinar om kunstig intelligens]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Her er man altså nødt til at tage andre metoder i brug, for at kunne dokumentere at man har udviklet sit produkt ordentligt og redeligt.&lt;br /&gt;
==Kildehenvisninger i dokumentation==&lt;br /&gt;
Der kan være forskellige standarder for hvordan man kildehenviser i forskellige uddannelser, dette er skrevet med udgangspunkt i at man anvender Word bibliografi-værktøj og her vist med en Harvard-lignende standard&amp;lt;ref&amp;gt;[https://holstebro-htx.dk/index.php/Word_Kildeliste Kildelister] anvendt i Microsoft Word&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Normal Internet-kilde til kode===&lt;br /&gt;
I dette eksempel er der angivet hvordan man ville dokumentere at man har anvendt kode fra et bibliotek til noget hardware på en [[Arduino]]. I det tænkte eksempel er det en 4 kanals AD-konverter&amp;lt;ref&amp;gt;[https://arduinotech.dk/shop/ads1115-module-4-channel-16-bit-i2c-adc-with-pro-gain-amplifier 4 kanals AD-konverter] fra ArduinoTech&amp;lt;/ref&amp;gt;, der er købt som modul.&lt;br /&gt;
&lt;br /&gt;
For at kunne anvende modulet i koden skal der kommunikeres med modulet på en måde, som er angivet i beskrivelsen af modulet - det er dog ikke nødvendigt at sætte sig ind i den grundlæggende kommunikation, hvis man blot ønsker at få værdier ind i sin software. Som en dokumentation for hvordan man anvender biblioteket kan man skrive følgende:&lt;br /&gt;
&lt;br /&gt;
====Eksempel på dokumentation====&lt;br /&gt;
Til at hente værdierne fra den 4 kanals AD-konverter anvendes et bibliotek fundet på GitHub (Singh, 2018) som kan indlæse de analoge spændinger.&lt;br /&gt;
Til at sætte AD-konverteren rigtigt op, til at kunne læse 4 spændinger, så anvendes eksemplet ”ADS1115_SingleEnded.ino” og i setup skrives følgende kode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
    ads.getAddr_ADS1115(ADS1115_DEFAULT_ADDRESS);   // 0x48, 1001 000 (ADDR = GND)&lt;br /&gt;
    ads.setGain(GAIN_TWO);          // 2x gain   +/- 2.048V  1 bit = 0.0625mV (default)&lt;br /&gt;
    ads.setMode(MODE_CONTIN);       // Continuous conversion mode&lt;br /&gt;
    ads.setRate(RATE_128);          // 128SPS (default)&lt;br /&gt;
    ads.setOSMode(OSMODE_SINGLE);   // Set to start a single-conversion&lt;br /&gt;
    ads.begin();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
I [[loop()]] testes i første omgang, om det kan lade sig gøre at læse de 4 kanaler. Dette gøres ved at afvikle følgende testkode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
    address = ads.ads_i2cAddress;&lt;br /&gt;
    Wire.beginTransmission(address);&lt;br /&gt;
    error = Wire.endTransmission();&lt;br /&gt;
    if (error == 0)&lt;br /&gt;
    {&lt;br /&gt;
        int16_t adc0, adc1, adc2, adc3;&lt;br /&gt;
&lt;br /&gt;
        adc0 = ads.Measure_SingleEnded(0);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 1: &amp;quot;);&lt;br /&gt;
        Serial.println(adc0);&lt;br /&gt;
        adc1 = ads.Measure_SingleEnded(1);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 2: &amp;quot;);&lt;br /&gt;
        Serial.println(adc1);&lt;br /&gt;
        adc2 = ads.Measure_SingleEnded(2);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 3: &amp;quot;);&lt;br /&gt;
        Serial.println(adc2);&lt;br /&gt;
        adc3 = ads.Measure_SingleEnded(3);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 4: &amp;quot;);&lt;br /&gt;
        Serial.println(adc3);&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Denne test giver det ønskede resultat.&lt;br /&gt;
&lt;br /&gt;
Ud fra denne beskrivelse viser man, at man tager andres kode, og anvender ind i sit eget projekt, og man angiver præcist i sin beskrivelse hvad man har taget fra andres kode.&lt;br /&gt;
&lt;br /&gt;
I kildelisten vil kilden optræde på følgende måde:&lt;br /&gt;
&lt;br /&gt;
Singh, Y., 2018. Arduino Library ADS1115 16 bit 4 channel ADC. [Online] &amp;lt;br /&amp;gt;&lt;br /&gt;
Available at: https://github.com/ncdcommunity/Arduino_Library_ADS1115_16Bit_4Channel_ADC&amp;lt;br /&amp;gt;&lt;br /&gt;
[Senest hentet eller vist den 15 marts 2024].&lt;br /&gt;
&lt;br /&gt;
==Referencer== &lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Programmering}}&lt;br /&gt;
&lt;br /&gt;
[[Kategori:Programmering teknik]]&lt;/div&gt;</summary>
		<author><name>Bar</name></author>
	</entry>
	<entry>
		<id>https://www.htxarduino.dk/index.php?title=Programmering_med_ChatGPT&amp;diff=5384</id>
		<title>Programmering med ChatGPT</title>
		<link rel="alternate" type="text/html" href="https://www.htxarduino.dk/index.php?title=Programmering_med_ChatGPT&amp;diff=5384"/>
		<updated>2024-03-15T12:06:53Z</updated>

		<summary type="html">&lt;p&gt;Bar: /* Normal Internet-kilde til kode */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Det er ikke så svært at få ChatGPT&amp;lt;ref&amp;gt;[https://chat.openai.com/auth/login ChatGPT Login] - Indgangen til ChatGPT&amp;lt;/ref&amp;gt; til at lave kode, der skal man blot beskrive hvad man gerne vil have programmet til at gøre, og så kopiere den kode, der kommer ud af det - det giver tit ret gode resultater.&lt;br /&gt;
&lt;br /&gt;
Problemet med at anvende ChatGPT i forbindelse med skoleprojekter er, at man har forståelsen med i det, og at man ikke kan blive anklaget for plagiat.&lt;br /&gt;
&lt;br /&gt;
==Hvad må man ikke i en skoleprojekt==&lt;br /&gt;
*Man må ikke kopiere kode, som man ikke selv har skrevet, til et programmeringsprodukt uden at man angiver en kilde. Det er uanset hvor koden stammer fra, også selvom man har brugt ChatGPT til at &amp;quot;udvikle&amp;quot; koden.&lt;br /&gt;
*Man må ikke aflevere et produkt hvor de primære dele af koden er kopieret, heller ikke selvom man kildehenviser.&lt;br /&gt;
*Man må ikke få ChatGPT til at dokumentere sin kode, ved at man kopierer ChatGPT&#039;s beskrivelse ind i sin dokumentation af koden.&lt;br /&gt;
&lt;br /&gt;
De beskrevne eksempler er at betragte som plagiat, og vil blive håndteret efter skolens ordensregler, hvilket i værste fald kan ende med at et fag annulleres eller man bliver bortvist fra uddannelsen.&lt;br /&gt;
==Hvad er tilladt med ChatGPT==&lt;br /&gt;
På samme måde som man må anvende kilder fra internettet, så må man i programmerings-faget i gymnasiet anvende ChatGPT i udviklingen af kode til et programmeringsprodukt. Dette er blevet tilladt via en revidering af vejledningen til faget&amp;lt;ref&amp;gt;[https://www.uvm.dk/-/media/filer/uvm/udd/gym/pdf23/aug/vejledninger/valgfag/230807-programmering-c--valgfag.pdf Vejledning] til Valgfaget Programmering C&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
I vejledningen står der som følger:&lt;br /&gt;
&lt;br /&gt;
: &#039;&#039;&amp;quot;brug af internettet er tilladt som fagligt hjælpemiddel ved de mundtlige prøver, inkluderer de tilladte hjælpemidler anvendelsen af chatbots og lignende på en måde, som afspejler, hvordan man arbejder i den daglige undervisning. Dette kunne fx være brug af ChatGPT til at debugge kode.&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Det skal altså afspejle den normale brug, som man også har ved at bruge internettet. Som angivet under hvad man ikke må, så er den normale brug, at man anvender information til at lære et programmere, men at man ikke tager så meget af sit produkt fra nettet, så man ikke har en forståelse af hvordan produktet er sammensat.&lt;br /&gt;
&lt;br /&gt;
Videre i vejledningen står der:&lt;br /&gt;
&lt;br /&gt;
: &#039;&#039;&amp;quot;I forhold til denne type hjælpemidler er det vigtigt at være opmærksom på, at den tilladte anvendelse er betinget af, at hjælpemidlerne kun benyttes i et omfang, hvor prøvebesvarelsen er selvstændig og udelukkende elevens egen.&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Igen understreges at det der afleveres skal være elevens selvstændigt udviklede produkt og dokumentation, hvor man på normal vis anvender internettet som et værktøj til at bibringe forståelse.&lt;br /&gt;
&lt;br /&gt;
==Problemet med ChatGPT==&lt;br /&gt;
Ligesom man ikke kan kilde-henvise til &amp;quot;google&amp;quot;, for at angive at man har fundet informationer på nettet, så kan man heller ikke kildehenvise til ChatGPT direkte som en kilde.&lt;br /&gt;
&lt;br /&gt;
Når man finder informationer med google&#039;, så skal man angive hvor på nettet man har fundet dem med så præcis en kildehenvisning, at man kan se den information der er blevet anvendt.&lt;br /&gt;
&lt;br /&gt;
Denne type henvisning kan man ikke lave i forhold til ChatGPT, da sprogmodellen der ligger bag ChatGPT konstant udvikler sig, samt at de svar sprogmodellen giver her et randomiseret element indbygget, som er med til at give bedre svar&amp;lt;ref&amp;gt;[https://www.it-vest.dk/arrangementer/sig-webinar-14-marts-2024-kunstig-intelligens-og-chatgpt-hvordan-virker-det-og-skal-vi-bare-opgive-undervisning-og-eksamen Webinar om kunstig intelligens]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Her er man altså nødt til at tage andre metoder i brug, for at kunne dokumentere at man har udviklet sit produkt ordentligt og redeligt.&lt;br /&gt;
==Kildehenvisninger i dokumentation==&lt;br /&gt;
Der kan være forskellige standarder for hvordan man kildehenviser i forskellige uddannelser, dette er skrevet med udgangspunkt i at man anvender Word bibliografi-værktøj og her vist med en Harvard-lignende standard&amp;lt;ref&amp;gt;[https://holstebro-htx.dk/index.php/Word_Kildeliste Kildelister] anvendt i Microsoft Word&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Normal Internet-kilde til kode===&lt;br /&gt;
I dette eksempel er der angivet hvordan man ville dokumentere at man har anvendt kode fra et bibliotek til noget hardware på en [[Arduino]]. I det tænkte eksempel er det en 4 kanals AD-konverter&amp;lt;ref&amp;gt;[https://arduinotech.dk/shop/ads1115-module-4-channel-16-bit-i2c-adc-with-pro-gain-amplifier 4 kanals AD-konverter] fra ArduinoTech&amp;lt;/ref&amp;gt;, der er købt som modul.&lt;br /&gt;
&lt;br /&gt;
For at kunne anvende modulet i koden skal der kommunikeres med modulet på en måde, som er angivet i beskrivelsen af modulet - det er dog ikke nødvendigt at sætte sig ind i den grundlæggende kommunikation, hvis man blot ønsker at få værdier ind i sin software. Som en dokumentation for hvordan man anvender biblioteket kan man skrive følgende:&lt;br /&gt;
&lt;br /&gt;
Til at hente værdierne fra den 4 kanals AD-konverter anvendes et bibliotek fundet på GitHub (Singh, 2018) som kan indlæse de analoge spændinger.&lt;br /&gt;
Til at sætte AD-konverteren rigtigt op, til at kunne læse 4 spændinger, så anvendes eksemplet ”ADS1115_SingleEnded.ino” og i setup skrives følgende kode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
    ads.getAddr_ADS1115(ADS1115_DEFAULT_ADDRESS);   // 0x48, 1001 000 (ADDR = GND)&lt;br /&gt;
    ads.setGain(GAIN_TWO);          // 2x gain   +/- 2.048V  1 bit = 0.0625mV (default)&lt;br /&gt;
    ads.setMode(MODE_CONTIN);       // Continuous conversion mode&lt;br /&gt;
    ads.setRate(RATE_128);          // 128SPS (default)&lt;br /&gt;
    ads.setOSMode(OSMODE_SINGLE);   // Set to start a single-conversion&lt;br /&gt;
    ads.begin();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
I [[loop()]] testes i første omgang, om det kan lade sig gøre at læse de 4 kanaler. Dette gøres ved at afvikle følgende testkode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
    address = ads.ads_i2cAddress;&lt;br /&gt;
    Wire.beginTransmission(address);&lt;br /&gt;
    error = Wire.endTransmission();&lt;br /&gt;
    if (error == 0)&lt;br /&gt;
    {&lt;br /&gt;
        int16_t adc0, adc1, adc2, adc3;&lt;br /&gt;
&lt;br /&gt;
        adc0 = ads.Measure_SingleEnded(0);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 1: &amp;quot;);&lt;br /&gt;
        Serial.println(adc0);&lt;br /&gt;
        adc1 = ads.Measure_SingleEnded(1);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 2: &amp;quot;);&lt;br /&gt;
        Serial.println(adc1);&lt;br /&gt;
        adc2 = ads.Measure_SingleEnded(2);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 3: &amp;quot;);&lt;br /&gt;
        Serial.println(adc2);&lt;br /&gt;
        adc3 = ads.Measure_SingleEnded(3);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 4: &amp;quot;);&lt;br /&gt;
        Serial.println(adc3);&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Denne test giver det ønskede resultat.&lt;br /&gt;
&lt;br /&gt;
Ud fra denne beskrivelse viser man, at man tager andres kode, og anvender ind i sit eget projekt, og man angiver præcist i sin beskrivelse hvad man har taget fra andres kode.&lt;br /&gt;
&lt;br /&gt;
I kildelisten vil kilden optræde på følgende måde:&lt;br /&gt;
&lt;br /&gt;
Singh, Y., 2018. Arduino Library ADS1115 16 bit 4 channel ADC. [Online] &amp;lt;br /&amp;gt;&lt;br /&gt;
Available at: https://github.com/ncdcommunity/Arduino_Library_ADS1115_16Bit_4Channel_ADC&amp;lt;br /&amp;gt;&lt;br /&gt;
[Senest hentet eller vist den 15 marts 2024].&lt;br /&gt;
&lt;br /&gt;
==Referencer== &lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Programmering}}&lt;br /&gt;
&lt;br /&gt;
[[Kategori:Programmering teknik]]&lt;/div&gt;</summary>
		<author><name>Bar</name></author>
	</entry>
	<entry>
		<id>https://www.htxarduino.dk/index.php?title=Programmering_med_ChatGPT&amp;diff=5383</id>
		<title>Programmering med ChatGPT</title>
		<link rel="alternate" type="text/html" href="https://www.htxarduino.dk/index.php?title=Programmering_med_ChatGPT&amp;diff=5383"/>
		<updated>2024-03-15T12:04:34Z</updated>

		<summary type="html">&lt;p&gt;Bar: /* Referencer */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Det er ikke så svært at få ChatGPT&amp;lt;ref&amp;gt;[https://chat.openai.com/auth/login ChatGPT Login] - Indgangen til ChatGPT&amp;lt;/ref&amp;gt; til at lave kode, der skal man blot beskrive hvad man gerne vil have programmet til at gøre, og så kopiere den kode, der kommer ud af det - det giver tit ret gode resultater.&lt;br /&gt;
&lt;br /&gt;
Problemet med at anvende ChatGPT i forbindelse med skoleprojekter er, at man har forståelsen med i det, og at man ikke kan blive anklaget for plagiat.&lt;br /&gt;
&lt;br /&gt;
==Hvad må man ikke i en skoleprojekt==&lt;br /&gt;
*Man må ikke kopiere kode, som man ikke selv har skrevet, til et programmeringsprodukt uden at man angiver en kilde. Det er uanset hvor koden stammer fra, også selvom man har brugt ChatGPT til at &amp;quot;udvikle&amp;quot; koden.&lt;br /&gt;
*Man må ikke aflevere et produkt hvor de primære dele af koden er kopieret, heller ikke selvom man kildehenviser.&lt;br /&gt;
*Man må ikke få ChatGPT til at dokumentere sin kode, ved at man kopierer ChatGPT&#039;s beskrivelse ind i sin dokumentation af koden.&lt;br /&gt;
&lt;br /&gt;
De beskrevne eksempler er at betragte som plagiat, og vil blive håndteret efter skolens ordensregler, hvilket i værste fald kan ende med at et fag annulleres eller man bliver bortvist fra uddannelsen.&lt;br /&gt;
==Hvad er tilladt med ChatGPT==&lt;br /&gt;
På samme måde som man må anvende kilder fra internettet, så må man i programmerings-faget i gymnasiet anvende ChatGPT i udviklingen af kode til et programmeringsprodukt. Dette er blevet tilladt via en revidering af vejledningen til faget&amp;lt;ref&amp;gt;[https://www.uvm.dk/-/media/filer/uvm/udd/gym/pdf23/aug/vejledninger/valgfag/230807-programmering-c--valgfag.pdf Vejledning] til Valgfaget Programmering C&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
I vejledningen står der som følger:&lt;br /&gt;
&lt;br /&gt;
: &#039;&#039;&amp;quot;brug af internettet er tilladt som fagligt hjælpemiddel ved de mundtlige prøver, inkluderer de tilladte hjælpemidler anvendelsen af chatbots og lignende på en måde, som afspejler, hvordan man arbejder i den daglige undervisning. Dette kunne fx være brug af ChatGPT til at debugge kode.&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Det skal altså afspejle den normale brug, som man også har ved at bruge internettet. Som angivet under hvad man ikke må, så er den normale brug, at man anvender information til at lære et programmere, men at man ikke tager så meget af sit produkt fra nettet, så man ikke har en forståelse af hvordan produktet er sammensat.&lt;br /&gt;
&lt;br /&gt;
Videre i vejledningen står der:&lt;br /&gt;
&lt;br /&gt;
: &#039;&#039;&amp;quot;I forhold til denne type hjælpemidler er det vigtigt at være opmærksom på, at den tilladte anvendelse er betinget af, at hjælpemidlerne kun benyttes i et omfang, hvor prøvebesvarelsen er selvstændig og udelukkende elevens egen.&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Igen understreges at det der afleveres skal være elevens selvstændigt udviklede produkt og dokumentation, hvor man på normal vis anvender internettet som et værktøj til at bibringe forståelse.&lt;br /&gt;
&lt;br /&gt;
==Problemet med ChatGPT==&lt;br /&gt;
Ligesom man ikke kan kilde-henvise til &amp;quot;google&amp;quot;, for at angive at man har fundet informationer på nettet, så kan man heller ikke kildehenvise til ChatGPT direkte som en kilde.&lt;br /&gt;
&lt;br /&gt;
Når man finder informationer med google&#039;, så skal man angive hvor på nettet man har fundet dem med så præcis en kildehenvisning, at man kan se den information der er blevet anvendt.&lt;br /&gt;
&lt;br /&gt;
Denne type henvisning kan man ikke lave i forhold til ChatGPT, da sprogmodellen der ligger bag ChatGPT konstant udvikler sig, samt at de svar sprogmodellen giver her et randomiseret element indbygget, som er med til at give bedre svar&amp;lt;ref&amp;gt;[https://www.it-vest.dk/arrangementer/sig-webinar-14-marts-2024-kunstig-intelligens-og-chatgpt-hvordan-virker-det-og-skal-vi-bare-opgive-undervisning-og-eksamen Webinar om kunstig intelligens]&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
Her er man altså nødt til at tage andre metoder i brug, for at kunne dokumentere at man har udviklet sit produkt ordentligt og redeligt.&lt;br /&gt;
==Kildehenvisninger i dokumentation==&lt;br /&gt;
Der kan være forskellige standarder for hvordan man kildehenviser i forskellige uddannelser, dette er skrevet med udgangspunkt i at man anvender Word bibliografi-værktøj og her vist med en Harvard-lignende standard&amp;lt;ref&amp;gt;[https://holstebro-htx.dk/index.php/Word_Kildeliste Kildelister] anvendt i Microsoft Word&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
===Normal Internet-kilde til kode===&lt;br /&gt;
I dette eksempel er der angivet hvordan man ville dokumentere at man har anvendt kode fra et bibliotek til noget hardware på en [[Arduino]]. I det tænkte eksempel er det en 4 kanals AD-konverter&amp;lt;ref&amp;gt;[https://arduinotech.dk/shop/ads1115-module-4-channel-16-bit-i2c-adc-with-pro-gain-amplifier 4 kanals AD-konverter] fra ArduinoTech&amp;lt;/ref&amp;gt;, der er købt som modul.&lt;br /&gt;
&lt;br /&gt;
For at kunne anvende modulet i koden skal der kommunikeres med modulet på en måde, som er angivet i beskrivelsen af modulet - det er dog ikke nødvendigt at sætte sig ind i den grundlæggende kommunikation, hvis man blot ønsker at få værdier ind i sin software. Som en dokumentation for hvordan man anvender biblioteket kan man skrive følgende:&lt;br /&gt;
&lt;br /&gt;
Til at hente værdierne fra den 4 kanals AD-konverter anvendes et bibliotek fundet på GitHub (Singh, 2018) som kan indlæse de analoge spændinger.&lt;br /&gt;
Til at sætte AD-konverteren rigtigt op, til at kunne læse 4 spændinger, så anvendes eksemplet ”ADS1115_SingleEnded.ino” og i setup skrives følgende kode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
    ads.getAddr_ADS1115(ADS1115_DEFAULT_ADDRESS);   // 0x48, 1001 000 (ADDR = GND)&lt;br /&gt;
    ads.setGain(GAIN_TWO);          // 2x gain   +/- 2.048V  1 bit = 0.0625mV (default)&lt;br /&gt;
    ads.setMode(MODE_CONTIN);       // Continuous conversion mode&lt;br /&gt;
    ads.setRate(RATE_128);          // 128SPS (default)&lt;br /&gt;
    ads.setOSMode(OSMODE_SINGLE);   // Set to start a single-conversion&lt;br /&gt;
    ads.begin();&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
I [[loop()]] testes i første omgang, om det kan lade sig gøre at læse de 4 kanaler. Dette gøres ved at afvikle følgende testkode:&lt;br /&gt;
&amp;lt;syntaxhighlight lang=&amp;quot;c&amp;quot;&amp;gt;&lt;br /&gt;
    address = ads.ads_i2cAddress;&lt;br /&gt;
    Wire.beginTransmission(address);&lt;br /&gt;
    error = Wire.endTransmission();&lt;br /&gt;
    if (error == 0)&lt;br /&gt;
    {&lt;br /&gt;
        int16_t adc0, adc1, adc2, adc3;&lt;br /&gt;
&lt;br /&gt;
        adc0 = ads.Measure_SingleEnded(0);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 1: &amp;quot;);&lt;br /&gt;
        Serial.println(adc0);&lt;br /&gt;
        adc1 = ads.Measure_SingleEnded(1);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 2: &amp;quot;);&lt;br /&gt;
        Serial.println(adc1);&lt;br /&gt;
        adc2 = ads.Measure_SingleEnded(2);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 3: &amp;quot;);&lt;br /&gt;
        Serial.println(adc2);&lt;br /&gt;
        adc3 = ads.Measure_SingleEnded(3);&lt;br /&gt;
        Serial.print(&amp;quot;Digital Value of Analog Input at Channel 4: &amp;quot;);&lt;br /&gt;
        Serial.println(adc3);&lt;br /&gt;
    }&lt;br /&gt;
&amp;lt;/syntaxhighlight&amp;gt;&lt;br /&gt;
Denne test giver det ønskede resultat.&lt;br /&gt;
&lt;br /&gt;
Ud fra denne beskrivelse viser man, at man tager andres kode, og anvender ind i sit eget projekt, og man angiver præcist i sin beskrivelse hvad man har taget fra andres kode.&lt;br /&gt;
I kildelisten vil kilden optræde på følgende måde:&lt;br /&gt;
Singh, Y. (16. januar 2018). Arduino Library ADS1115 16 bit 4 channel ADC. Hentet 15. marts 2024 fra https://github.com/ncdcommunity/Arduino_Library_ADS1115_16Bit_4Channel_ADC&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
==Referencer== &lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Programmering}}&lt;br /&gt;
&lt;br /&gt;
[[Kategori:Programmering teknik]]&lt;/div&gt;</summary>
		<author><name>Bar</name></author>
	</entry>
	<entry>
		<id>https://www.htxarduino.dk/index.php?title=Programmering_med_ChatGPT&amp;diff=5382</id>
		<title>Programmering med ChatGPT</title>
		<link rel="alternate" type="text/html" href="https://www.htxarduino.dk/index.php?title=Programmering_med_ChatGPT&amp;diff=5382"/>
		<updated>2024-03-15T11:19:31Z</updated>

		<summary type="html">&lt;p&gt;Bar: /* Hvad er tilladt med ChatGPT */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Det er ikke så svært at få ChatGPT&amp;lt;ref&amp;gt;[https://chat.openai.com/auth/login ChatGPT Login] - Indgangen til ChatGPT&amp;lt;/ref&amp;gt; til at lave kode, der skal man blot beskrive hvad man gerne vil have programmet til at gøre, og så kopiere den kode, der kommer ud af det - det giver tit ret gode resultater.&lt;br /&gt;
&lt;br /&gt;
Problemet med at anvende ChatGPT i forbindelse med skoleprojekter er, at man har forståelsen med i det, og at man ikke kan blive anklaget for plagiat.&lt;br /&gt;
&lt;br /&gt;
==Hvad må man ikke i en skoleprojekt==&lt;br /&gt;
*Man må ikke kopiere kode, som man ikke selv har skrevet, til et programmeringsprodukt uden at man angiver en kilde. Det er uanset hvor koden stammer fra, også selvom man har brugt ChatGPT til at &amp;quot;udvikle&amp;quot; koden.&lt;br /&gt;
*Man må ikke aflevere et produkt hvor de primære dele af koden er kopieret, heller ikke selvom man kildehenviser.&lt;br /&gt;
*Man må ikke få ChatGPT til at dokumentere sin kode, ved at man kopierer ChatGPT&#039;s beskrivelse ind i sin dokumentation af koden.&lt;br /&gt;
&lt;br /&gt;
De beskrevne eksempler er at betragte som plagiat, og vil blive håndteret efter skolens ordensregler, hvilket i værste fald kan ende med at et fag annulleres eller man bliver bortvist fra uddannelsen.&lt;br /&gt;
==Hvad er tilladt med ChatGPT==&lt;br /&gt;
På samme måde som man må anvende kilder fra internettet, så må man i programmerings-faget i gymnasiet anvende ChatGPT i udviklingen af kode til et programmeringsprodukt. Dette er blevet tilladt via en revidering af vejledningen til faget&amp;lt;ref&amp;gt;[https://www.uvm.dk/-/media/filer/uvm/udd/gym/pdf23/aug/vejledninger/valgfag/230807-programmering-c--valgfag.pdf Vejledning] til Valgfaget Programmering C&amp;lt;/ref&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
I vejledningen står der som følger:&lt;br /&gt;
&lt;br /&gt;
: &#039;&#039;&amp;quot;brug af internettet er tilladt som fagligt hjælpemiddel ved de mundtlige prøver, inkluderer de tilladte hjælpemidler anvendelsen af chatbots og lignende på en måde, som afspejler, hvordan man arbejder i den daglige undervisning. Dette kunne fx være brug af ChatGPT til at debugge kode.&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Det skal altså afspejle den normale brug, som man også har ved at bruge internettet. Som angivet under hvad man ikke må, så er den normale brug, at man anvender information til at lære et programmere, men at man ikke tager så meget af sit produkt fra nettet, så man ikke har en forståelse af hvordan produktet er sammensat.&lt;br /&gt;
&lt;br /&gt;
Videre i vejledningen står der:&lt;br /&gt;
&lt;br /&gt;
: &#039;&#039;&amp;quot;I forhold til denne type hjælpemidler er det vigtigt at være opmærksom på, at den tilladte anvendelse er betinget af, at hjælpemidlerne kun benyttes i et omfang, hvor prøvebesvarelsen er selvstændig og udelukkende elevens egen.&amp;quot;&#039;&#039;&lt;br /&gt;
&lt;br /&gt;
Igen understreges at det der afleveres skal være elevens selvstændigt udviklede produkt og dokumentation, hvor man på normal vis anvender internettet som et værktøj til at bibringe forståelse.&lt;br /&gt;
&lt;br /&gt;
==Referencer== &lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
&lt;br /&gt;
{{Programmering}}&lt;br /&gt;
&lt;br /&gt;
[[Kategori:Programmering teknik]]&lt;/div&gt;</summary>
		<author><name>Bar</name></author>
	</entry>
</feed>