亚洲精品久久久久久久久久久,亚洲国产精品一区二区制服,亚洲精品午夜精品,国产成人精品综合在线观看,最近2019中文字幕一页二页

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線(xiàn)課程
  • 觀看技術(shù)視頻
  • 寫(xiě)文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

樹(shù)莓派遇上ChatGPT,魔法熱線(xiàn)就此誕生!

上海晶珩電子科技有限公司 ? 2025-04-13 09:04 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

盡管這種電話(huà)在幾十年前就已過(guò)時(shí),但許多人都對(duì)旋轉(zhuǎn)撥號(hào)電話(huà)記憶猶新。這些舊電話(huà),其實(shí)可以被改造成一個(gè) ChatGPT 熱線(xiàn)。這個(gè)由 Pollux Labs 開(kāi)發(fā)的項(xiàng)目,讓你可以將一部復(fù)古的旋轉(zhuǎn)撥號(hào)電話(huà)連接到樹(shù)莓派上,拿起聽(tīng)筒、撥號(hào),就能享受由 AI 驅(qū)動(dòng)的對(duì)話(huà),仿佛回到了傳統(tǒng)的電話(huà)時(shí)代。

樹(shù)莓派負(fù)責(zé)語(yǔ)音識(shí)別、文本生成和語(yǔ)音播放,ChatGPT 會(huì)記住通話(huà)中的每一句話(huà)。這意味著你可以體驗(yàn)到將老式撥號(hào)與尖端人工智能相結(jié)合的獨(dú)特互動(dòng)?,F(xiàn)在,讓我們來(lái)看看這是如何實(shí)現(xiàn)的。

將旋轉(zhuǎn)電話(huà)改造成 ChatGPT 熱線(xiàn)的理由

許多人喜歡使用旋轉(zhuǎn)電話(huà)的復(fù)古感,盡管通話(huà)內(nèi)容是現(xiàn)代的,但它的撥號(hào)聲和重量能把你帶回過(guò)去。ChatGPT 增添了有趣且由語(yǔ)音驅(qū)動(dòng)的體驗(yàn),與在鍵盤(pán)上打字完全不同。你還可以欣賞將電話(huà)的揚(yáng)聲器、麥克風(fēng)和撥號(hào)盤(pán)連接到樹(shù)莓派的工程挑戰(zhàn)。除此之外,這是一個(gè)有趣的方式,可以重用舊技術(shù)。

通過(guò)電話(huà)聽(tīng)到 ChatGPT 的回應(yīng)可以激發(fā)創(chuàng)造力。你可以在轉(zhuǎn)移到語(yǔ)音助手之前,整合音樂(lè)、新聞更新或引入其他 AI 服務(wù)。實(shí)踐是學(xué)習(xí)的關(guān)鍵,這個(gè)項(xiàng)目同時(shí)探索了硬件和軟件。它展示了簡(jiǎn)單電子設(shè)備的靈活性。最重要的是,旋轉(zhuǎn)撥號(hào)與 AI 對(duì)話(huà)會(huì)讓任何嘗試過(guò)它的人感到驚喜和愉悅。

電話(huà)改造成 ChatGPT 熱線(xiàn)所需的必備物品

首先,你需要一部有足夠的空間容納樹(shù)莓派和電線(xiàn)的旋轉(zhuǎn)撥號(hào)電話(huà)。70 年代或 80 年代的電話(huà)型號(hào)通常內(nèi)部空間較大,你可以整理電線(xiàn)而無(wú)需鉆孔。你至少需要一臺(tái)樹(shù)莓派 4B,但樹(shù)莓派 5 的性能會(huì)更好。

你還需要一個(gè)麥克風(fēng)來(lái)捕捉音頻,并將樹(shù)莓派的音頻輸出連接到電話(huà)的揚(yáng)聲器。一個(gè) USB 領(lǐng)夾麥克風(fēng)或小型 USB 麥克風(fēng)適配器應(yīng)該可以完美地安裝在機(jī)殼內(nèi)部。

你可能會(huì)問(wèn),為什么要使用領(lǐng)夾麥克風(fēng)而不是電話(huà)聽(tīng)筒中內(nèi)置的麥克風(fēng)。事實(shí)證明,嘗試使用聽(tīng)筒的麥克風(fēng)很困難,特別是因?yàn)樾D(zhuǎn)撥號(hào)電話(huà)中使用的麥克風(fēng)是模擬的而不是數(shù)字的。

接下來(lái),收集必要的電子工具,如烙鐵、剪線(xiàn)鉗和萬(wàn)用表。這些工具可以幫助你確認(rèn)撥號(hào)的脈沖線(xiàn)、測(cè)試連接,并將樹(shù)莓派的音頻輸出連接到電話(huà)的揚(yáng)聲器線(xiàn)。你還需要與樹(shù)莓派 GPIO 引腳匹配的跳線(xiàn)或連接器,可能還需要一個(gè)小按鈕來(lái)檢測(cè)聽(tīng)筒是在線(xiàn)還是離線(xiàn)。

在軟件方面,安裝用于語(yǔ)音識(shí)別、文本轉(zhuǎn)語(yǔ)音和 OpenAI APIPython 庫(kù)。獲取 OpenAI API 密鑰,并在你的 Python 腳本中引用它,以生成 ChatGPT 回復(fù)。

完成改造并構(gòu)建 ChatGPT 熱線(xiàn)的步驟

將電話(huà)和樹(shù)莓派改造成新用途涉及仔細(xì)的接線(xiàn)和軟件配置。在此指南中,你將學(xué)習(xí)如何拆卸電話(huà)、識(shí)別撥號(hào)脈沖,并設(shè)置樹(shù)莓派以實(shí)現(xiàn)語(yǔ)音轉(zhuǎn)文本和文本轉(zhuǎn)語(yǔ)音轉(zhuǎn)換。仔細(xì)驗(yàn)證每根電線(xiàn)和引腳分配,因?yàn)橐粋€(gè)不匹配可能會(huì)導(dǎo)致錯(cuò)誤。

1. 取下電話(huà)蓋,找到揚(yáng)聲器線(xiàn)、旋轉(zhuǎn)撥號(hào)線(xiàn),以及任何可以連接按鈕以檢測(cè)掛鉤狀態(tài)的地方。

48702934-1803-11f0-9434-92fbcf53809c.png

2. 剝?nèi)?3.5 毫米音頻電纜的外皮,將 2.8 毫米平板連接器焊接到電話(huà)聽(tīng)筒的地線(xiàn)和一個(gè)聲道線(xiàn)上。然后,將其連接到聽(tīng)筒的連接插座。

4890f2a4-1803-11f0-9434-92fbcf53809c.png48aeaa2e-1803-11f0-9434-92fbcf53809c.png

3. 在電話(huà)內(nèi)部放置一個(gè) USB 麥克風(fēng)(或適配器),確保你的樹(shù)莓派可以清晰地接收聲音。

48be9722-1803-11f0-9434-92fbcf53809c.png

4. 使用萬(wàn)用表確認(rèn)哪些撥號(hào)線(xiàn)承載脈沖。將這些線(xiàn)連接到 GPIO 引腳和地線(xiàn)。然后,連接掛鉤按鈕,使軟件能夠感應(yīng)到何時(shí)提起聽(tīng)筒。

48d21da6-1803-11f0-9434-92fbcf53809c.png48e274bc-1803-11f0-9434-92fbcf53809c.png


48eee152-1803-11f0-9434-92fbcf53809c.png

5. 在你的樹(shù)莓派 上安裝必要的音頻庫(kù),包括 PyAudio、PyGame 和 OpenAI 客戶(hù)端。下載或創(chuàng)建音頻文件(如撥號(hào)音)以供播放,并將你的 OpenAI 密鑰存儲(chǔ)在 .env 文件中。

6. 接下來(lái),你需要一個(gè) Python 腳本,用于從麥克風(fēng)捕獲音頻,將其發(fā)送到 ChatGPT 進(jìn)行處理,并通過(guò)電話(huà)揚(yáng)聲器播放 AI 的回應(yīng)。你可以編寫(xiě)自己的腳本或使用 Pollux Labs 編寫(xiě)的腳本。只需確保根據(jù)自己的需求調(diào)整 GPIO 引腳編號(hào)、音頻設(shè)置和特殊文本提示。

7. 手動(dòng)運(yùn)行腳本以確認(rèn)其正常工作。一旦你聽(tīng)到撥號(hào)音且 ChatGPT 對(duì)你的聲音做出回應(yīng),添加一個(gè)系統(tǒng)服務(wù),以便在樹(shù)莓派啟動(dòng)時(shí)自動(dòng)啟動(dòng)電話(huà)。

如果你無(wú)法訪(fǎng)問(wèn)腳本,以下是供你參考的腳本。

#!/usr/bin/env python3"""ChatGPT for Rotary Phonehttps://en.polluxlabs.netMIT LicenseCopyright (c) 2025 Frederik KumbartzkiPermission is hereby granted, free of charge, to any person obtaining a copyof this software and associated documentation files (the "Software"), to dealin the Software without restriction, including without limitation the rightsto use, copy, modify, merge, publish, distribute, sublicense, and/or sellcopies of the Software, and to permit persons to whom the Software isfurnished to do so, subject to the following conditions:The above copyright notice and this permission notice shall be included in allcopies or substantial portions of the Software.THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS ORIMPLIED,

INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THEAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHERLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THESOFTWARE."""import osimport sysimport timeimport threadingfrom queue import Queuefrom pathlib import PathAudio and speech librariesos.environ['PYGAME_HIDE_SUPPORT_PROMPT'] ="hide"import pygameimport pyaudioimport numpy as npimport wavefrom openai import OpenAIOpenAI API Keyfrom dotenv import load_dotenvload_dotenv()OPENAI_API_KEY = os.environ.get("OPENAI_API_KEY")if not OPENAI_API_KEY:print("Error: OPENAI_API_KEY not found.")sys.exit(1)Hardware librariesfrom gpiozero import ButtonConstants and configurationsAUDIO_DIR ="/home/pi/Desktop/callGPT"AUDIO_FILES =

{"tone": f"{AUDIO_DIR}/a440.mp3","try_again": f"{AUDIO_DIR}/tryagain.mp3","error": f"{AUDIO_DIR}/error.mp3"}DIAL_PIN = 23# GPIO pin for rotary dialSWITCH_PIN = 17# GPIO pin for hook switchAudio parametersAUDIO_FORMAT = pyaudio.paInt16CHANNELS = 1SAMPLE_RATE = 16000CHUNK_SIZE = 1024SILENCE_THRESHOLD = 500MAX_SILENCE_CHUNKS = 20# About 1.3 seconds of silenceDEBOUNCE_TIME = 0.1# Time in seconds for debouncing button inputsclass AudioManager:"""Manages audio playback and recording."""def__init__(self):pygame.mixer.init(frequency=44100, buffer=2048)self.playing_audio = Falseself.audio_thread = NoneCreate temp directoryself.temp_dir

= Path(__file__).parent /"temp_audio"self.temp_dir.mkdir(exist_ok=True)Preload soundsself.sounds = {}for name, path in AUDIO_FILES.items():try:self.sounds[name] = pygame.mixer.Sound(path)except:print(f"Error loading {path}")def play_file(self, file_path, wait=True):try:sound = pygame.mixer.Sound(file_path)channel = sound.play()if wait and channel:while channel.get_busy():pygame.time.Clock().tick(30)except:pygame.mixer.music.load(file_path)pygame.mixer.music.play()if wait:while pygame.mixer.music.get_busy():pygame.time.Clock().tick(30)def start_continuous_tone(self):self.playing_audio = Trueif self.audio_thread and self.audio_thread.is_alive():self.playing_audio = Falseself.audio_thread.join(timeout=1.0)self.audio_thread = threading.Thread(target=self._play_continuous_tone)self.audio_thread.daemon = Trueself.audio_thread.start()def _play_continuous_tone(self):try:if"tone"in self.sounds:self.sounds["tone"].play(loops=-1)while self.playing_audio:time.sleep(0.1)self.sounds["tone"].stop()else:pygame.mixer.music.load(AUDIO_FILES["tone"])pygame.mixer.music.play(loops=-1)while self.playing_audio:time.sleep(0.1)pygame.mixer.music.stop()except Exception as e:print(f"Error during tone playback: {e}")def stop_continuous_tone(self):self.playing_audio = Falseif"tone"in self.sounds:self.sounds["tone"].stop()if pygame.mixer.get_init() and pygame.mixer.music.get_busy():pygame.mixer.music.stop()class SpeechRecognizer:"""Handles real-time speech recognition using OpenAI's Whisper API."""def__init__(self, openai_client):self.client = openai_clientself.audio = pyaudio.PyAudio()self.stream = Nonedef capture_and_transcribe(self):Setup audio stream if not already initializedif not self.stream:self.stream = self.audio.open(format=AUDIO_FORMAT,channels=CHANNELS,rate=SAMPLE_RATE,input=True,frames_per_buffer=CHUNK_SIZE,)Set up queue and threadingaudio_queue = Queue()stop_event = threading.Event()Start audio capture threadcapture_thread = threading.Thread(target=self._capture_audio,args=(audio_queue, stop_event))capture_thread.daemon = Truecapture_thread.start()Process the audioresult = self._process_audio(audio_queue, stop_event)Cleanupstop_event.set()capture_thread.join()return resultdef _capture_audio(self, queue, stop_event):while not stop_event.is_set():try:data = self.stream.read(CHUNK_SIZE, exception_on_overflow=False)queue.put(data)except KeyboardInterrupt:breakdef _process_audio(self, queue, stop_event):buffer = b""speaking = Falsesilence_counter = 0while not stop_event.is_set():if not queue.empty():chunk = queue.get()Check volumedata_np = np.frombuffer(chunk, dtype=np.int16)volume = np.abs(data_np).mean()Detect speakingif volume > SILENCE_THRESHOLD:speaking = Truesilence_counter = 0elif speaking:silence_counter += 1Add chunk to bufferbuffer += chunkProcess if we've detected end of speechif speaking and silence_counter > MAX_SILENCE_CHUNKS:print("Processing speech...")Save to temp filetemp_file = Path(__file__).parent /"temp_recording.wav"self._save_audio(buffer, temp_file)Transcribetry:return self._transcribe_audio(temp_file)except Exception as e:print(f"Error during transcription: {e}")buffer = b""speaking = Falsesilence_counter = 0return Nonedef _save_audio(self, buffer, file_path):with wave.open(str(file_path),"wb") as

wf:wf.setnchannels(CHANNELS)wf.setsampwidth(self.audio.get_sample_size(AUDIO_FORMAT))wf.setframerate(SAMPLE_RATE)wf.writeframes(buffer)def _transcribe_audio(self, file_path):with open(file_path,"rb") as audio_file:transcription = self.client.audio.transcriptions.create(model="whisper-1",file=audio_file,language="en")return transcription.textdef cleanup(self):if self.stream:self.stream.stop_stream()self.stream.close()self.stream = Noneif self.audio:self.audio.terminate()self.audio = Noneclass ResponseGenerator:"""Generates and speaks streaming responses from OpenAI's API."""def__init__(self, openai_client, temp_dir):self.client = openai_clientself.temp_dir = temp_dirself.answer =""def generate_streaming_response(self, user_input, conversation_history=None):self.answer =""collected_messages = []chunk_files = []Audio playback queue and control variablesaudio_queue = Queue()playing_event = threading.Event()stop_event = threading.Event()Start the audio playback threadplayback_thread = threading.Thread(target=self._audio_playback_worker,args=(audio_queue, playing_event, stop_event))playback_thread.daemon = Trueplayback_thread.start()Prepare messagesmessages = [{"role":"system","content":"You are a humorous conversation partner engaged in a natural phone call. Keep your answers concise and to the point."}]Use conversation history if available, but limit to last 4 pairsif conversation_history and len(conversation_history) > 0:if len(conversation_history) > 8:conversation_history = conversation_history[-8:]messages.extend(conversation_history)else:messages.append({"role":"user","content": user_input})Stream the responsestream = self.client.chat.completions.create(model="gpt-4o-mini",messages=messages,stream=True)Variables for sentence chunkingsentence_buffer =""chunk_counter = 0for chunk in stream:if chunk.choices and hasattr(chunk.choices[0], 'delta') and hasattr(chunk.choices[0].delta, 'content'):content = chunk.choices[0].delta.contentif content:collected_messages.append(content)sentence_buffer += contentProcess when we have a complete sentence or phraseif any(end in content for end in [".","!","?",":"]) or len(sentence_buffer) > 100:Generate speech for this chunkchunk_file_path = self.temp_dir / f"chunk_{chunk_counter}.mp3"try:Generate speechresponse = self.client.audio.speech.create(model="tts-1",voice="alloy",input=sentence_buffer,speed=1.0)response.stream_to_file(str(chunk_file_path))chunk_files.append(str(chunk_file_path))Add to playback queueaudio_queue.put(str(chunk_file_path))Signal playback thread if it's waitingplaying_event.set()except Exception as e:print(f"Error generating speech for chunk: {e}")Reset buffer and increment countersentence_buffer =""chunk_counter += 1Process any remaining textif sentence_buffer.strip():chunk_file_path = self.temp_dir / f"chunk_{chunk_counter}.mp3"try:response = self.client.audio.speech.create(model="tts-1",voice="alloy",input=sentence_buffer,speed=1.2)response.stream_to_file(str(chunk_file_path))chunk_files.append(str(chunk_file_path))audio_queue.put(str(chunk_file_path))playing_event.set()except Exception as e:print(f"Error generating final speech chunk: {e}")Signal end of generationaudio_queue.put(None)# Sentinel to signal end of queueWait for playback to completeplayback_thread.join()stop_event.set()# Ensure the thread stopsCombine all messagesself.answer ="".join(collected_messages)print(self.answer)Clean up temp filesself._cleanup_temp_files(chunk_files)return self.answerdef _audio_playback_worker(self, queue, playing_event, stop_event):while not stop_event.is_set():Wait for a signal that there's something to playif queue.empty():playing_event.wait(timeout=0.1)playing_event.clear()continueGet the next file to playfile_path = queue.get()None is our sentinel value to signal end of queueif file_path is None:breaktry:Play audio and wait for completionpygame.mixer.music.load(file_path)pygame.mixer.music.play()Wait for playback to complete before moving to next chunkwhile pygame.mixer.music.get_busy() and not stop_event.is_set():pygame.time.Clock().tick(30)Small pause between chunks for more natural flowtime.sleep(0.05)except Exception as e:print(f"Error playing audio chunk: {e}")def _cleanup_temp_files(self, file_list):Wait a moment to ensure files aren't in usetime.sleep(0.5)for file_path in file_list:try:if os.path.exists(file_path):os.remove(file_path)except Exception as e:print(f"Error removing temp file: {e}")class RotaryDialer:"""Handles rotary phone dialing and services."""def__init__(self, openai_client):self.client = openai_clientself.audio_manager = AudioManager()self.speech_recognizer = SpeechRecognizer(openai_client)self.response_generator = ResponseGenerator(openai_client, self.audio_manager.temp_dir)Set up GPIOself.dial_button = Button(DIAL_PIN, pull_up=True)self.switch = Button(SWITCH_PIN, pull_up=True)State variablesself.pulse_count = 0self.last_pulse_time = 0self.running = Truedef start(self):Set up callbacksself.dial_button.when_pressed = self._pulse_detectedself.switch.when_released = self._handle_switch_releasedself.switch.when_pressed = self._handle_switch_pressedStart in ready stateif not self.switch.is_pressed:Receiver is picked upself.audio_manager.start_continuous_tone()else:Receiver is on hookprint("Phone in idle state. Pick up the receiver to begin.")print("Rotary dial ready. Dial a number when the receiver is picked up.")try:self._main_loop()except KeyboardInterrupt:print("Terminating...")self._cleanup()def _main_loop(self):while self.running:self._check_number()time.sleep(0.1)def _pulse_detected(self):if not self.switch.is_pressed:current_time = time.time()if current_time - self.last_pulse_time >

DEBOUNCE_TIME:self.pulse_count += 1self.last_pulse_time = current_timedef _check_number(self):if not self.switch.is_pressed and self.pulse_count > 0:self.audio_manager.stop_continuous_tone()time.sleep(1.5)# Wait between digitsif self.pulse_count == 10:self.pulse_count = 0# "0" is sent as 10 pulsesprint("Dialed service number:", self.pulse_count)if self.pulse_count == 1:self._call_gpt_service()Return to dial tone after conversationif not self.switch.is_pressed:

# Only if the receiver wasn't hung upself._reset_state()self.pulse_count = 0def _call_gpt_service(self):Conversation history for contextconversation_history = []first_interaction = TrueFor faster transitionsspeech_recognizer = self.speech_recognizerresponse_generator = self.response_generatorPreparation for next recordingnext_recording_thread = Nonenext_recording_queue = Queue()Conversation loop - runs until the receiver is hung upwhile not self.switch.is_pressed:If there's a prepared next recording thread, use its resultif next_recording_thread:next_recording_thread.join()recognized_text = next_recording_queue.get()next_recording_thread = Noneelse:Only during first iteration or as fallbackprint("Listening..."+ (" (Speak now)"if first_interactionelse""))

first_interaction = FalseStart audio processingrecognized_text = speech_recognizer.capture_and_transcribe()if not recognized_text:print("Could not recognize your speech")self.audio_manager.play_file(AUDIO_FILES["try_again"])continueprint("Understood:", recognized_text)Update conversation historyconversation_history.append({"role":"user","content": recognized_text

})

Start the next recording thread PARALLEL to API responsenext_recording_thread = threading.Thread(target=self._background_capture,args=(speech_recognizer, next_recording_queue))next_recording_thread.daemon = Truenext_recording_thread.start()Generate the responseresponse = response_generator.generate_streaming_response(recognized_text, conversation_history)Add response to historyconversation_history.append({"role":"assistant","content": response})Check if the receiver was hung up in the meantimeif self.switch.is_pressed:breakIf we get here, the receiver was hung upif next_recording_thread and next_recording_thread.is_alive():next_recording_thread.join(timeout=0.5)def _background_capture(self, recognizer, result_queue):try:result = recognizer.capture_and_transcribe()result_queue.put(result)except Exception as e:print

(f"Error in background recording: {e}")result_queue.put(None)def _reset_state(self):self.pulse_count = 0self.audio_manager.stop_continuous_tone()self.audio_manager.start_continuous_tone

()print("Rotary dial ready. Dial a number.")def _handle_switch_released(self):print("Receiver picked up - System restarting")self._restart_script()def _handle_switch_pressed(self):print("Receiver hung up - System

terminating")self._cleanup()self.running = FalseComplete termination after short delaythreading.Timer(1.0, self._restart_script).start()returndef _restart_script(self):print("Script restarting...")self.audio_manager.stop_continuous_tone()os.execv(sys.executable, ['python'] + sys.argv)def _cleanup(self):Terminate Audio Managerself.audio_manager.stop_continuous_tone()Terminate Speech Recognizer if it existsif hasattr(self, 'speech_recognizer') and self.speech_recognizer:self.speech_recognizer.cleanup()print("Resources have been released.")def main():Initialize OpenAI clientclient = OpenAI(api_key=OPENAI_API_KEY)Create and start the rotary dialerdialer = RotaryDialer(client)dialer.start

()print("Program terminated.")ifname=="__main__":main()

回顧你所做的任何連接或配置的優(yōu)化。每種電話(huà)型號(hào)都有細(xì)微差別,因此你可能需要進(jìn)行一些實(shí)驗(yàn)。在電話(huà)外殼內(nèi)給樹(shù)莓派通電,以簡(jiǎn)化故障排除,直到你確信一切正常。一旦你通過(guò)聽(tīng)筒聽(tīng)到 ChatGPT 的回應(yīng),你的旋轉(zhuǎn)電話(huà)熱線(xiàn)就幾乎完成了。

享受復(fù)古體驗(yàn),同時(shí)訪(fǎng)問(wèn)現(xiàn)代 AI

用 ChatGPT 為舊式旋轉(zhuǎn)電話(huà)注入活力,將懷舊與創(chuàng)新融為一體。撥打電話(huà)給 AI,展示了過(guò)去與現(xiàn)在技術(shù)之間的神奇互動(dòng)。隨著時(shí)間的推移,你可以通過(guò)不同的聲音、語(yǔ)言或提示來(lái)個(gè)性化你的腳本,以改變 ChatGPT 的回應(yīng)。

你甚至可以整合更多的 AI 服務(wù),用于閱讀新聞、播放播客或安排日程。這個(gè)項(xiàng)目可以讓你接觸電子設(shè)備和 Python 編程,因?yàn)槟阏趶浐夏M電話(huà)和數(shù)字 AI 之間的鴻溝。完成此項(xiàng)目后,你將擁有一部功能齊全的旋轉(zhuǎn)電話(huà),它充當(dāng) ChatGPT 的熱線(xiàn)。享受你的復(fù)古未來(lái)主義對(duì)話(huà),并探索為你的電話(huà) AI 伙伴的新想法。

參考文章:

https://www.xda-developers.com/take-chatgpt-retro-raspberry-pi-powered-rotary-phone-hotline/

如果覺(jué)得文章不錯(cuò)記得點(diǎn)贊,收藏,關(guān)注,轉(zhuǎn)發(fā)~

聲明:本文內(nèi)容及配圖由入駐作者撰寫(xiě)或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 樹(shù)莓派
    +關(guān)注

    關(guān)注

    122

    文章

    2067

    瀏覽量

    109162
  • ChatGPT
    +關(guān)注

    關(guān)注

    30

    文章

    1595

    瀏覽量

    9951
收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    關(guān)于樹(shù)莓那個(gè)標(biāo)簽2011.12

    話(huà)咨詢(xún)這個(gè)問(wèn)題。其實(shí)沒(méi)什么,2011.12,不是大家想的這個(gè)樹(shù)莓的生產(chǎn)日期,更加不是中國(guó)進(jìn)行翻版的時(shí)間,2011.12只是一個(gè)紀(jì)念日罷了。因?yàn)榈谝粋€(gè)樹(shù)莓
    發(fā)表于 09-10 18:58

    樹(shù)莓的深刻含義

    要想玩轉(zhuǎn)樹(shù)莓,首先得知道樹(shù)莓是什么。在本節(jié)中,作者將帶領(lǐng)大家揭開(kāi)樹(shù)莓的神秘面紗,了解
    發(fā)表于 08-06 06:10

    樹(shù)莓4B+古董PC1500智能編曲音源合成器實(shí)驗(yàn)

    樹(shù)莓4B+古董PC1500wifi通訊,關(guān)于ChatGPT的MudicLM智能AI編曲,控制音源芯片聲卡合成器實(shí)驗(yàn)。
    發(fā)表于 03-07 10:52

    樹(shù)莓創(chuàng)始人Eben中國(guó)行,聯(lián)手創(chuàng)客改變世界

    Eben Upton,樹(shù)莓基金會(huì)的共同創(chuàng)始人,被譽(yù)為樹(shù)莓這個(gè)神奇機(jī)器背后的魔法師,現(xiàn)在他即將啟動(dòng)中國(guó)之旅,將這
    發(fā)表于 07-29 15:36 ?4382次閱讀

    樹(shù)莓裝機(jī)教程

    樹(shù)莓裝機(jī)教程樹(shù)莓裝機(jī)教程樹(shù)莓裝機(jī)教程樹(shù)莓
    發(fā)表于 11-25 10:14 ?52次下載

    樹(shù)莓的種類(lèi)_樹(shù)莓安裝教程

    樹(shù)莓(Raspberry Pi)是尺寸僅有信用卡大小的一個(gè)小型電腦,您可以將樹(shù)莓連接電視、顯示器、鍵盤(pán)鼠標(biāo)等設(shè)備使用。目前,樹(shù)莓
    發(fā)表于 11-27 22:01 ?5778次閱讀

    樹(shù)莓3wifi配置_樹(shù)莓3開(kāi)啟wifi熱點(diǎn)_樹(shù)莓3的wifi使用教程

    樹(shù)莓3在2016年2月29號(hào)正式發(fā)布了,樹(shù)莓3幾乎和樹(shù)莓2代板型一致,大外觀沒(méi)什么變化小電
    發(fā)表于 12-08 11:47 ?3.2w次閱讀

    樹(shù)莓3硬件配置_樹(shù)莓3都能裝什么系統(tǒng)_樹(shù)莓3系統(tǒng)安裝教程

    樹(shù)莓3一直頗受電子發(fā)燒友的青睞,這篇文章主要討論的就是樹(shù)莓3的硬件配置、樹(shù)莓3都能裝什么系
    發(fā)表于 12-08 14:36 ?2.7w次閱讀

    樹(shù)莓有什么用_樹(shù)莓能用來(lái)做啥_樹(shù)莓新手入門(mén)教程

    本文首先介紹了樹(shù)莓的功能,其次介紹了樹(shù)莓的用途,最后詳細(xì)介紹了樹(shù)莓新手入門(mén)教程。
    的頭像 發(fā)表于 05-08 14:15 ?3.4w次閱讀

    樹(shù)莓是什么樹(shù)莓的簡(jiǎn)單介紹

    要想玩轉(zhuǎn)樹(shù)莓,首先得知道樹(shù)莓是什么。在本節(jié)中,作者將帶領(lǐng)大家揭開(kāi)樹(shù)莓的神秘面紗,了解
    發(fā)表于 05-15 18:09 ?31次下載
    <b class='flag-5'>樹(shù)莓</b><b class='flag-5'>派</b>是什么<b class='flag-5'>樹(shù)莓</b><b class='flag-5'>派</b>的簡(jiǎn)單介紹

    樹(shù)莓3和樹(shù)莓4的原理圖免費(fèi)下載

    本文檔的主要內(nèi)容詳細(xì)介紹的是樹(shù)莓3和樹(shù)莓4的原理圖免費(fèi)下載。
    發(fā)表于 01-07 10:23 ?234次下載
    <b class='flag-5'>樹(shù)莓</b><b class='flag-5'>派</b>3和<b class='flag-5'>樹(shù)莓</b><b class='flag-5'>派</b>4的原理圖免費(fèi)下載

    樹(shù)莓控制步進(jìn)電機(jī)

    樹(shù)莓控制步進(jìn)電機(jī) 前言 設(shè)備 連接 源碼 前言 測(cè)試步進(jìn)電機(jī) 設(shè)備 名稱(chēng) 型號(hào) 樹(shù)莓 3B+ 步進(jìn)電機(jī) 28BYJ-48-5V 步進(jìn)電機(jī)驅(qū)動(dòng)板 UL2003芯片驅(qū)動(dòng)板連接
    發(fā)表于 03-21 11:39 ?1次下載
    <b class='flag-5'>樹(shù)莓</b><b class='flag-5'>派</b>控制步進(jìn)電機(jī)

    樹(shù)莓是x86還是arm

    樹(shù)莓(Raspberry Pi)是一款由英國(guó)樹(shù)莓基金會(huì)(Raspberry Pi Foundation)開(kāi)發(fā)的微型計(jì)算機(jī)。它基于ARM架構(gòu),而非x86架構(gòu)。 一、
    的頭像 發(fā)表于 08-30 15:42 ?3101次閱讀

    樹(shù)莓GUI應(yīng)用開(kāi)發(fā):從零到炫酷的魔法之旅!

    各位樹(shù)莓的粉絲們!今天我要帶你們踏上一段神奇的旅程——探索樹(shù)莓派上GUI應(yīng)用的無(wú)限可能!你是不是覺(jué)得樹(shù)莓只能用來(lái)跑跑服務(wù)器、做個(gè)簡(jiǎn)單的項(xiàng)
    的頭像 發(fā)表于 04-04 09:03 ?772次閱讀
    <b class='flag-5'>樹(shù)莓</b><b class='flag-5'>派</b>GUI應(yīng)用開(kāi)發(fā):從零到炫酷的<b class='flag-5'>魔法</b>之旅!

    樹(shù)莓分類(lèi)器:用樹(shù)莓識(shí)別不同型號(hào)的樹(shù)莓

    在本教程系列的第一部分中,您將學(xué)習(xí)如何使用樹(shù)莓AI攝像頭來(lái)檢測(cè)不同的樹(shù)莓型號(hào)。本系列由DavidPlowman創(chuàng)建,他是樹(shù)莓
    的頭像 發(fā)表于 06-13 16:39 ?817次閱讀
    <b class='flag-5'>樹(shù)莓</b><b class='flag-5'>派</b>分類(lèi)器:用<b class='flag-5'>樹(shù)莓</b><b class='flag-5'>派</b>識(shí)別不同型號(hào)的<b class='flag-5'>樹(shù)莓</b><b class='flag-5'>派</b>!